<!DOCTYPE html><html lang="zh-cn"><head><link rel=manifest href=/manifest.json><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="format-detection" content="telephone=no"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="icon" href="/images/icons/icon.jpg?v=2.0.0-rc.0" type="image/png" sizes="16x16"><link rel="icon" href="/images/icons/icon.jpg?v=2.0.0-rc.0" type="image/png" sizes="32x32"><meta name="description" content="背书专用">
<meta name="keywords" content="技术探究">
<meta property="og:type" content="article">
<meta property="og:title" content="数据库总结">
<meta property="og:url" content="https:&#x2F;&#x2F;mikyming.online&#x2F;2021&#x2F;10&#x2F;13&#x2F;%E6%95%B0%E6%8D%AE%E5%BA%93&#x2F;">
<meta property="og:site_name" content="MikyMing&#39;s Blog">
<meta property="og:description" content="背书专用">
<meta property="og:locale" content="zh-cn">
<meta property="og:updated_time" content="2021-12-07T15:15:31.976Z">
<meta name="twitter:card" content="summary"><meta name="keywords" content="MikyMing, MikyMing's Blog"><meta name="description" content="技术,生活"><title>数据库总结 | MikyMing's Blog</title><link ref="canonical" href="https://mikyming.online/2021/10/13/%E6%95%B0%E6%8D%AE%E5%BA%93/"><link rel="alternate" href="/atom.xml" type="application/atom+xml"><link rel="dns-prefetch" href="https://cdn.jsdelivr.net"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.12.1/css/all.min.css" type="text/css"><link rel="stylesheet" href="/css/index.css?v=2.0.0-rc.0"><script>var Stun = window.Stun || {};
var CONFIG = {
  root: '/',
  algolia: undefined,
  fontIcon: {"prompt":{"success":"fas fa-check-circle","info":"fas fa-arrow-circle-right","warning":"fas fa-exclamation-circle","error":"fas fa-times-circle"},"copyBtn":"fas fa-copy"},
  sidebar: {"offsetTop":"20px","tocMaxDepth":6},
  header: {"enable":true,"showOnPost":false,"scrollDownIcon":true},
  postWidget: {"endText":true},
  nightMode: {"enable":true},
  back2top: {"enable":true},
  codeblock: {"style":"default","highlight":"ocean","wordWrap":false},
  reward: false,
  fancybox: false,
  zoomImage: {"gapAside":"20px"},
  galleryWaterfall: undefined,
  lazyload: false,
  pjax: undefined,
  externalLink: {"icon":{"enable":true,"name":"fas fa-external-link-alt"}},
  shortcuts: {"switchPost":true},
  prompt: {"copyButton":"Copy","copySuccess":"Copy Success","copyError":"Copy Error"},
  sourcePath: {"js":"js","css":"css","images":"images"},
};

window.CONFIG = CONFIG;</script></head><body><div class="container" id="container"><header class="header" id="header"><div class="header-inner header-inner--height header-inner--bgcolor"><nav class="header-nav header-nav--sticky"><div class="header-nav-inner"><div class="header-nav-menubtn"><i class="fas fa-bars"></i></div><div class="header-nav-menu"><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/"><span class="header-nav-menu-item__icon"><i class="fas fa-home"></i></span><span class="header-nav-menu-item__text">Home</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/archives/"><span class="header-nav-menu-item__icon"><i class="fas fa-folder-open"></i></span><span class="header-nav-menu-item__text">Archives</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/categories/"><span class="header-nav-menu-item__icon"><i class="fas fa-layer-group"></i></span><span class="header-nav-menu-item__text">Categories</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/tags/"><span class="header-nav-menu-item__icon"><i class="fas fa-tags"></i></span><span class="header-nav-menu-item__text">Tags</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="javascript:;" target="_blank" rel="noopener" onclick="return false;"><span class="header-nav-menu-item__icon"><i class="fa fa-address-book"></i></span><span class="header-nav-menu-item__text">友链</span></a><div class="header-nav-submenu"><div class="header-nav-submenu-item"><a class="header-nav-submenu-item__link" href="https://www.bobby285271.top/" target="_blank" rel="noopener"><span class="header-nav-submenu-item__text">BobbyRong</span></a></div><div class="header-nav-submenu-item"><a class="header-nav-submenu-item__link" href="https://blog.ojhdt.com/" target="_blank" rel="noopener"><span class="header-nav-submenu-item__text">ojhdt</span></a></div></div></div></div><div class="header-nav-search"><span class="header-nav-search__icon"><i class="fas fa-search"></i></span><span class="header-nav-search__text">Search</span></div><div class="header-nav-mode"><div class="mode"><div class="mode-track"><span class="mode-track-moon"></span><span class="mode-track-sun"></span></div><div class="mode-thumb"></div></div></div></div></nav></div></header><main class="main" id="main"><div class="main-inner"><div class="content-wrap" id="content-wrap"><div class="content" id="content"><!-- Just used to judge whether it is an article page--><div id="is-post"></div><div class="post"><header class="post-header"><h1 class="post-title">数据库总结</h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">Created</span><span class="post-meta-item__value">2021-10-13</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">Updated</span><span class="post-meta-item__value">2021-12-07</span></span><span class="post-meta-item post-meta-item--wordcount"><span class="post-meta-item__icon"><i class="far fa-file-word"></i></span><span class="post-meta-item__info">Words</span><span class="post-meta-item__value">15.7k</span></span><span class="post-meta-item post-meta-item--visitors"><span class="post-meta-item__icon" data-popover="Visitors" data-popover-pos="up"><i class="fas fa-eye"></i></span><span class="post-meta-item__value" id="busuanzi_value_page_pv"></span></span></div></header><div class="post-body"><p>背书专用</p>
<a id="more"></a>

<p>[TOC]</p>

        <h2 id="绪论"   >
          <a href="#绪论" class="heading-link"><i class="fas fa-link"></i></a>绪论</h2>
      
        <h3 id="数据管理的三个阶段"   >
          <a href="#数据管理的三个阶段" class="heading-link"><i class="fas fa-link"></i></a>数据管理的三个阶段</h3>
      <ul>
<li><p>人工管理阶段</p>
</li>
<li><p>文件系统阶段</p>
</li>
<li><p>数据库系统阶段</p>

        <h3 id="基本术语"   >
          <a href="#基本术语" class="heading-link"><i class="fas fa-link"></i></a>基本术语</h3>
      </li>
<li><p>数据（Data）</p>
<ul>
<li>计算机用来描述事物的记录（文字．图形．图像．声音）</li>
<li>数据的形式本身并不能完全表达其内容，需要经过语义解释。数据与其语义是不可分的</li>
</ul>
</li>
<li><p>数据库（Database，简称DB）</p>
<ul>
<li>数据库是长期存储在计算机内有结构的大量的共享的数据集合。</li>
</ul>
</li>
<li><p>数据库管理系统（DBMS）</p>
<ul>
<li>数据库管理系统是位于用户与操作系统之间的一层数据管理软件。</li>
<li>数据库在建立、运用和维护时由数据库管理系统统一管理、统一控制。</li>
<li>数据库系统（DBS）<ul>
<li>数据库系统是指在计算机系统中引入数据库后的系统构成，一般由数据库、数据库管理系统（及其开发工具）、应用系统、数据库管理员和用户构成。 </li>
</ul>
</li>
</ul>
</li>
<li><p>数据冗余度：</p>
<ul>
<li>指同一数据重复存储时的重复程度。 </li>
</ul>
</li>
<li><p>数据的安全性（Security）</p>
<ul>
<li>数据的安全性是指保护数据，防止不合法使用数据造成数据的泄密和破坏，使每个用户只能按规定，对某些数据以某些方式进行访问和处理。 </li>
</ul>
</li>
<li><p>数据的完整性（Integrity）</p>
<ul>
<li>数据的完整性指数据的正确性、有效性和相容性。即将数据控制在有效的范围内，或要求数据之间满足一定的关系。 </li>
</ul>
</li>
<li><p>并发（Concurrency）控制</p>
<ul>
<li>当多个用户的并发进程同时存取、修改数据库时，可能会发生相互干扰而得到错误的结果并使得数据库的完整性遭到破坏，因此必须对多用户的并发操作加以控制和协调。</li>
</ul>
</li>
<li><p>数据库恢复（Recovery）</p>
<ul>
<li>计算机系统的硬件故障、软件故障、操作员的失误以及故意的破坏也会影响数据库中数据的正确性，甚至造成数据库部分或全部数据的丢失。DBMS必须具有将数据库从错误状态恢复到某一已知的正确状态（亦称为完整状态或一致状态）的功能。
        <h3 id="数据库的三要素"   >
          <a href="#数据库的三要素" class="heading-link"><i class="fas fa-link"></i></a>数据库的三要素</h3>
      </li>
</ul>
</li>
<li><p>数据（描述事物的符号记录，数据库里面存储的内容） </p>
</li>
<li><p>存储器（外存，一般是硬盘，数据库的载体）</p>
</li>
<li><p>数据库管理系统（DBMS，数据库的管理软件）</p>

        <h3 id="数据模型"   >
          <a href="#数据模型" class="heading-link"><i class="fas fa-link"></i></a>数据模型</h3>
      </li>
<li><p>模型</p>
<ul>
<li>是现实世界特征的模拟和抽象</li>
</ul>
</li>
<li><p>数据模型</p>
<ul>
<li>也是一种模型，它是现实世界数据特征的抽象，表示实体以及实体间的联系</li>
<li>一个用于描述数据、数据间关系、数据语义和数据约束的概念工具的集合</li>
</ul>
</li>
<li><p>两级模型的抽象</p>
<ul>
<li>一是概念模型<ul>
<li>（也称信息模型，用于信息世界的建模），它是按用户的观点来对数据和信息建模，主要用于数据库设计。这类模型强调其语义表达能力，要能够较方便、直接地表达应用中的各种语义知识，这类模型应为概念简单、清晰、易于用户理解，是用户和数据库设计人员之间进行交流的语言。</li>
</ul>
</li>
<li>二是数据模型<ul>
<li>（如层次、网状、关系模型，用于机器世界），它是按计算机系统的观点对数据建模，主要用于DBMS的实现。这类模型通常需要有严格的形式化定义，而且常常会加上一些限制或规定，以便于机器上的实现。还通常有一组严格定义了语法和语义的语言，人们可以使用它来定义、操纵数据库中的数据。</li>
</ul>
</li>
</ul>
</li>
<li><p>数据模型的三要素</p>
<ul>
<li>（1） 数据结构<ul>
<li>数据结构是所研究的对象类型（Object Type）的集合。这些对象是数据库的组成部分。一般可分为两类：一类是与数据类型、内容、性质有关的对象，如网状模型中的数据项、记录，关系模型中的属性、关系等；一类是与数据之间联系有关的对象，如网状模型中的系型（Set Type）等。</li>
</ul>
</li>
<li>（2） 数据操作<ul>
<li>数据操作是指对数据库中各种对象（型）的实例（值）允许执行的操作的集合。数据库主要有检索和更新（插入、删除、修改）两大类操作。</li>
<li>数据结构是对系统静态特性的描述，数据操作是对系统动态特性的描述。</li>
</ul>
</li>
<li>（3） 数据的约束条件<ul>
<li>数据的约束条件是完整性规则的集合。完整性规则是给定的数据模型中数据及其联系所具有的制约和依存规则，用以限定符合数据模型的数据状态以及状态的变化，以保证数据的正确、有效、相容。</li>
</ul>
</li>
</ul>
</li>
<li><p>概念模型</p>
<ul>
<li>实体（Entity）<ul>
<li>客观存在并可相互区别的事物称为实体。实体可以是具体的人、事、物，也可以是抽象的概念或联系，如学生、部门、课程、银行帐户、选课、订货、演出、比赛等。</li>
</ul>
</li>
<li>属性（Attribute）<ul>
<li>实体所具有的某一特性称为属性。如学生实体可以由学号、姓名、性别、出生年月、系、入学时间等属性组成</li>
</ul>
</li>
<li>码（关键字，Key）<ul>
<li>唯一标识实体的（最小的）属性集称为码。例如学号学生实体的码</li>
</ul>
</li>
<li>域（Domain）<ul>
<li>属性的取值范围称为该属性的域。例如学号的域为8位整数，姓名的域为字符串集合，，性别的域为（男，女）。</li>
</ul>
</li>
<li>实体型（Entity Type）<ul>
<li>具有相同属性的实体必然具有共同的特征和性质。用实体名及其属性名集合来抽象和刻划同类实体，称为实体型。例如：学生（学号，姓名，性别，出生年月，系，入学时间）</li>
</ul>
</li>
<li>实体集（Entity Set）<ul>
<li>同型实体的集合称为实体集。例如，全体学生就是一个实体集。</li>
</ul>
</li>
<li>联系（Relationship）<ul>
<li>在现实世界中，事物内部以及事物之间是有联系的，这些联系在信息世界中反映为实体（型）内部的联系和实体（型）之间的联系。〖组成实体的各属性之间以及不同实体集之间的联系〗
        <h3 id="联系的种类"   >
          <a href="#联系的种类" class="heading-link"><i class="fas fa-link"></i></a>联系的种类</h3>
      </li>
</ul>
</li>
</ul>
</li>
<li><p>1对1联系</p>
<ul>
<li>定义：若对于实体集A中的每一个实体，实体集B中至多有一个实体与之联系，反之亦然，则称实体集A与实体集B具有一对一联系，记为1:1。</li>
</ul>
</li>
<li><p>1对多联系</p>
<ul>
<li>定义：若对于实体集A中的每一个实体，实体集B中有n个实体(n≥0)与之联系，反之，对于对于实体集B中的每一个实体，实体集A中至多只有一个实体与之联系，则称实体集A与实体集B具有一对多联系，记为1:n</li>
</ul>
</li>
<li><p>多对多联系</p>
<ul>
<li>定义：若对于实体集A中的每一个实体，实体集B中有n个实体(n≥0)与之联系，反之，对于对于实体集B中的每一个实体，实体集A中也有m个实体(m≥0)与之联系，则称实体集A与实体集B具有多对多联系，记为m:n
        <h3 id="概念模型的表示方法"   >
          <a href="#概念模型的表示方法" class="heading-link"><i class="fas fa-link"></i></a>概念模型的表示方法</h3>
      </li>
</ul>
</li>
<li><p>E-R图</p>
<ul>
<li>使用长方形来表示实体型，框内写上实体名</li>
<li>椭圆型表示实体的属性，并用无向边把实体和属性连接起来</li>
<li>用菱形表示实体间的联系，菱形框内写上联系名，用无向边把菱形分别与有关实体相连接，在无向边旁标上联系的类型，若实体之间联系也具有属性，则把属性和菱形也用无向边连接上</li>
<li>
        <h3 id="基本数据模型"   >
          <a href="#基本数据模型" class="heading-link"><i class="fas fa-link"></i></a>基本数据模型</h3>
      </li>
</ul>
</li>
<li><p>层次模型(Hierarchical Model)</p>
<ul>
<li>最早使用的一种模型</li>
<li>数据结构是一棵有向树</li>
<li>特点<ul>
<li>(1) 有且仅有一个结点无双亲，该结点称为根结点。</li>
<li>(2) 其他结点有且只有一个双亲</li>
</ul>
</li>
</ul>
</li>
<li><p>网状模型(Network Model)</p>
<ul>
<li>数据结构是一个有向图</li>
<li>特点<ul>
<li>（1）有一个以上的结点没有双亲</li>
<li>（2）结点可以有多于一个的双亲</li>
</ul>
</li>
<li>能表示实体之间的多种复杂联系</li>
</ul>
</li>
<li><p>关系模型(Relational Model)</p>
<ul>
<li>关系模型是用二维表格结构来表示实体及实体之间的联系的模型</li>
<li>数据结构是一个“二维表框架”组成的集合</li>
<li>关系模型概念简单,清晰,用户易懂易用,有严格的数学基础</li>
<li>大多数数据库系统都是关系型的</li>
<li>主要术语<ul>
<li>关系：一个关系对应于我们平常讲的一张表</li>
<li>元组：表中的一行称为一个元组</li>
<li>属性：表中的一列称为属性，每列的名称为属性名</li>
<li>主码：表中的某个属性组，它们的值唯一的标识一个元组</li>
<li>域：属性的取值范围</li>
<li>分量：元组中的一个属性值</li>
<li>关系模式：对关系的描述，用关系名（属性名1，属性名2，…，属性名n）来表示</li>
</ul>
</li>
<li>特点<ul>
<li><ol>
<li>概念单一：<ul>
<li>实体或实体之间的联系都用关系表示</li>
<li>用户的观点里，数据的逻辑结构就是表</li>
</ul>
</li>
</ol>
</li>
<li><ol start="2">
<li>关系必须是规范化的关系<ul>
<li>指在关系模型中，每一个关系模式要满足一定的要求或者称为规范条件</li>
<li>其最基本的要求是每一个分量是一个不可分的数据项，也就是说，不允许表中还有表。</li>
</ul>
</li>
</ol>
</li>
<li><ol start="3">
<li>用户对数据的检索操作不过是从原来的表中得到一张新的表<ul>
<li>在用户眼中，无论是原始数据还是结果数据，都是同一种数据结构——二维表。</li>
<li>数据操作是集合操作，即操作对象和操作结果都是若干元组的集合，而不象非关系模型中那样单记录的操作方式。</li>
<li>把存取路径向用户隐藏起来，提高了数据的独立性。
        <h3 id="数据库系统的体系结构"   >
          <a href="#数据库系统的体系结构" class="heading-link"><i class="fas fa-link"></i></a>数据库系统的体系结构</h3>
      </li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>三层模式：外模式、模式、内模式 </p>
<ul>
<li>外模式<ul>
<li>又称为用户模式，是数据库用户和数据库系统的接口，是数据库用户的数据视图，是数据库用户可以看见和使用的局部数据的逻辑结构和特征的描述</li>
<li>一个数据库通常都有多个外模式。一个应用程序只能使用一个外模式，但同一外模式可为多个应用程序所用</li>
</ul>
</li>
<li>模式<ul>
<li>可细分为概念模式和逻辑模式，是所有数据库用户的公共数据视图，是数据库中全部数据的逻辑结构和特征的描述。 </li>
<li>•一个数据库只有一个模式。模式不但要描述数据的逻辑结构，还要描述数据之间的联系、数据的完整性、安全性要求。 </li>
</ul>
</li>
<li>内模式<ul>
<li>又称为存储模式，是数据库物理结构和存储方式的描述，是数据在数据库内部的表示方式。 </li>
<li>•一个数据库只有一个内模式。内模式并不涉及物理记录，也不涉及硬件设备。</li>
</ul>
</li>
</ul>
</li>
<li><p>•二层映象功能：外模式/模式映象和模式/内模式映象 </p>
<ul>
<li>三层模式关系<ul>
<li>数据库模式是数据库的核心和关键，外模式通常是模式的子集。数据按外模式的描述提供给用户，按内模式的描述存储在硬盘上，而模式介于外、内模式之间，既不涉及外部的访问，也不涉及内部的存储，从而起到隔离作用，有利于保持数据的独立性，内模式依赖于全局逻辑结构，但可以独立于具体的存储设备</li>
</ul>
</li>
<li>映象<ul>
<li>是一种对应规则，说明映象双方如何进行转换。 </li>
</ul>
</li>
<li>外模式/模式映象<ul>
<li>作用：把描述局部逻辑结构的外模式与描述全局逻辑结构的模式联系趣来</li>
<li>当模式改变时，只要对外模式/模式映象做相应的改变，使外模式保持不变，则以外模式为依据的应用程序不受影响，从而保证了数据与程序之间的逻辑独立性，也就是数据的逻辑独立性 </li>
</ul>
</li>
<li>模式/内模式映象<ul>
<li>作用：把描述全局逻辑结构的模式与描述物理结构的内模式联系起来</li>
<li>当内模式改变时，比如存储设备或存储方式有所改变，只要模式/内模式映象做相应的改变，使模式保持不变，则应用程序就不受影响，从而保证了数据与程序之的物理独立性。
        <h2 id="关系模型"   >
          <a href="#关系模型" class="heading-link"><i class="fas fa-link"></i></a>关系模型</h2>
      
        <h3 id="关系模型组成的三要素"   >
          <a href="#关系模型组成的三要素" class="heading-link"><i class="fas fa-link"></i></a>关系模型组成的三要素</h3>
      </li>
</ul>
</li>
</ul>
</li>
<li><p>关系数据结构</p>
<ul>
<li>基本概念<ul>
<li>关系</li>
<li>关系模式<ul>
<li>什么是关系模式<ul>
<li>关系模式（Relation Schema）是型</li>
</ul>
</li>
<li>关系是值<ul>
<li>关系模式是对关系的描述</li>
</ul>
</li>
</ul>
</li>
<li>关系数据库</li>
</ul>
</li>
</ul>
</li>
<li><p>关系操作集合</p>
</li>
<li><p>关系完整性约束</p>
<ul>
<li>关系模型的完整性规则是对关系的某种约束条件</li>
<li>实体完整性和参照完整性是关系模型必须满足的完整性约束条件，被称作是关系的两个不变性，应该由关系系统自动支持。
        <h3 id="基本关系的六大性质"   >
          <a href="#基本关系的六大性质" class="heading-link"><i class="fas fa-link"></i></a>基本关系的六大性质</h3>
      </li>
</ul>
</li>
<li><p>① 列是同质的（Homogeneous）</p>
<ul>
<li>每一列中的分量是同一类型的数据，来自同一个域</li>
</ul>
</li>
<li><p>② 不同的列可出自同一个域</p>
<ul>
<li>其中的每一列称为一个属性</li>
<li>不同的属性要给予不同的属性名</li>
</ul>
</li>
<li><p>③ 列的顺序无所谓</p>
<ul>
<li>列的次序可以任意交换</li>
<li>遵循这一性质的数据库产品(如ORACLE)，增加新属性时，永远是插至最后一列。但也有许多关系数据库产品没有遵循这一性质，例如FoxPro仍然区分了属性顺序</li>
</ul>
</li>
<li><p>④ 任意两个元组的候选码不能完全相同</p>
<ul>
<li>候选码是可以惟一标识一个元组的属性或属性组。若一个关系中的候选码有多个，则选择一个作为主码</li>
</ul>
</li>
<li><p>⑤ 行的顺序无所谓</p>
<ul>
<li>行的次序可以任意交换</li>
<li>遵循这一性质的数据库产品(如ORACLE)，插入一个元组时永远插至最后一行。但也有许多关系数据库产品没有遵循这一性质，例如FoxPro仍然区分了元组的顺序</li>
</ul>
</li>
<li><p>⑥ 分量必须取原子值</p>
<ul>
<li>每一个分量都必须是不可分的数据项。
        <h3 id="关系模型中的三类完整性约束"   >
          <a href="#关系模型中的三类完整性约束" class="heading-link"><i class="fas fa-link"></i></a>关系模型中的三类完整性约束</h3>
      </li>
</ul>
</li>
<li><p>实体完整性</p>
</li>
<li><p>参照完整性</p>
<ul>
<li>外码（Foreign Key）</li>
</ul>
</li>
<li><p>用户定义的完整性</p>

        <h2 id="关系代数"   >
          <a href="#关系代数" class="heading-link"><i class="fas fa-link"></i></a>关系代数</h2>
      
        <h3 id="概述"   >
          <a href="#概述" class="heading-link"><i class="fas fa-link"></i></a>概述</h3>
      </li>
<li><p>关系代数是一种抽象的查询语言，用对关系的运算来表达查询，作为研究关系数据语言的数学工具。</p>
</li>
<li><p>关系代数的运算对象是关系，运算结果亦为关系。 </p>

        <h3 id="关系代数的运算"   >
          <a href="#关系代数的运算" class="heading-link"><i class="fas fa-link"></i></a>关系代数的运算</h3>
      </li>
<li><p>普通的集合运算</p>
<ul>
<li>并、交、差</li>
</ul>
</li>
<li><p>删除部分关系的运算</p>
<ul>
<li>选择、投影</li>
</ul>
</li>
<li><p>合并两个关系元组的运算</p>
<ul>
<li>连接、积</li>
</ul>
</li>
<li><p>改名运算</p>

        <h3 id="关系代数-1"   >
          <a href="#关系代数-1" class="heading-link"><i class="fas fa-link"></i></a>关系代数</h3>
      </li>
<li><p>并Union (∪)</p>
<ul>
<li>R和S的并，R∪S，是在R或S或两者中的元素的集合</li>
<li>一个元素在并集中只出现一次</li>
<li>R和S必须同类型（属性集相同、次序相同，但属性名可以不同）</li>
</ul>
</li>
<li><p>交Intersect (∩)</p>
<ul>
<li>R和S的交，R∩S，是在R和S中都存在的元素的集合</li>
<li>一个元素在交集中只出现一次</li>
<li>R和S必须同类型（属性集相同、次序相同，但属性名可以不同）</li>
</ul>
</li>
<li><p>差Minus (-)</p>
<ul>
<li>R和S的差，R-S，是在R中而不在S中的元素的集合</li>
<li>R和S必须同类型（属性集相同、次序相同，但属性名可以不同）</li>
</ul>
</li>
<li><p>投影Projection(π)</p>
<ul>
<li>从关系R中选择若干属性组成新的关系</li>
<li>πA1,A2,…,An(R),表示从R中选择属性集A1,A2,…,An组成新的关系</li>
<li>列的运算</li>
<li>投影运算的结果中,也要去除可能的重复元组</li>
</ul>
</li>
<li><p>广义笛卡儿积(×)</p>
<ul>
<li>关系R、S的广义笛卡儿积是两个关系的元组对的集合所组成的新关系</li>
<li>R×S：<ul>
<li>属性是R和S的组合（有重复）</li>
<li>元组是R和S所有元组的可能组合</li>
<li>是R、S的无条件连接，使任意两个关系的信息能组合在一起</li>
</ul>
</li>
</ul>
</li>
<li><p>选择Selection(σ)</p>
<ul>
<li>从关系R中选择符合条件的元组构成新的关系</li>
<li>σC(R),表示从R中选择满足条件(使逻辑表达式C为真)的元组</li>
<li>行的运算</li>
</ul>
</li>
<li><p>条件连接(θ)</p>
<ul>
<li>从R×S的结果集中，选取在指定的属性集上满足AθB条件的元组，组成新的关系</li>
<li>θ是一个关于属性集的比较运算符</li>
<li>θ为“＝”的连接运算称为等值连接。</li>
</ul>
</li>
<li><p>自然连接</p>
<ul>
<li>从R×S的结果集中，选取在某些公共属性上具有相同值的元组，组成新的关系</li>
<li>R、S的公共属性<ul>
<li>属性集的交集（名称及类型相同）</li>
</ul>
</li>
<li>公共属性在结果中只出现一次</li>
<li>等值连接</li>
</ul>
</li>
<li><p>关系代数—除( ÷ )</p>
<ul>
<li>给定关系R(X,Y)和S(Y,Z)，其中X, Y, Z为属性组。R中的Y与S中的Y可以有不同的属性名，但必须出自相同的域集。R与S的除运算得到一个新的关系P(X)，P是R中满足下列条件的元组在X属性列上的投影：元组在X上分量值x的象集Yx包含S在Y上投影的集合。</li>
<li>R÷S = {tr[X]| tr∈R∧πy       (S)Yx} </li>
<li>其中Yx为x在R中的象集，x=tr[X]。 </li>
<li>例子
        <h2 id="数据库语言SQL"   >
          <a href="#数据库语言SQL" class="heading-link"><i class="fas fa-link"></i></a>数据库语言SQL</h2>
      
        <h3 id="SQL的发展"   >
          <a href="#SQL的发展" class="heading-link"><i class="fas fa-link"></i></a>SQL的发展</h3>
      </li>
</ul>
</li>
<li><p>1974年，由Boyce和Chamberlin提出</p>
</li>
<li><p>1975~1979，IBM San Jose Research Lab的关系数据库管理系统原型System R实施了这种语言</p>
</li>
<li><p>SQL-86是第一个SQL标准</p>
</li>
<li><p>SQL-89、SQL-92(SQL2)、SQL-99(SQL3)</p>

        <h3 id="非过程化语言"   >
          <a href="#非过程化语言" class="heading-link"><i class="fas fa-link"></i></a>非过程化语言</h3>
      </li>
<li><p>SQL语言进行数据库操作时，只需要提出“做什么”，不需要指明“怎么做”。“怎么做”是由DBMS来完成</p>

        <h3 id="SQL的形式"   >
          <a href="#SQL的形式" class="heading-link"><i class="fas fa-link"></i></a>SQL的形式</h3>
      </li>
<li><p>交互式SQL</p>
<ul>
<li>一般DBMS都提供联机交互工具</li>
<li>用户可直接键入SQL命令对数据库进行操作</li>
<li>由DBMS来进行解释</li>
</ul>
</li>
<li><p>嵌入式SQL</p>
<ul>
<li>能将SQL语句嵌入到高级语言（宿主语言）</li>
<li>使应用程序充分利用SQL访问数据库的能力、宿主语言的过程处理能力</li>
<li>一般需要预编译，将嵌入的SQL语句转化为宿主语言编译器能处理的语句
        <h3 id="SQL语言主要组成部分"   >
          <a href="#SQL语言主要组成部分" class="heading-link"><i class="fas fa-link"></i></a>SQL语言主要组成部分</h3>
      </li>
</ul>
</li>
<li><p>数据定义语言（DDL，Data Definition Language）</p>
<ul>
<li>数据定义语言是指用来定义和管理数据库以及数据库中的各种对象的语句，这些语句包括CREATE、ALTER和DROP等语句。在SQL Server中，数据库对象包括表、视图、触发器、存储过程、规则、缺省、用户自定义的数据类型等。这些对象的创建、修改和删除等都可以通过使用CREATE、ALTER、DROP等语句来完成。</li>
<li>常见的数据类型<ul>
<li>字符型：<ul>
<li>定长字符型 char(n) 由于是定长，所以速度快</li>
<li>变长字符型 varchar(n)   </li>
</ul>
</li>
<li>数值型：<ul>
<li>整型 int(或integer)   -231~+231</li>
<li>短整型 smallint -215~+215的</li>
<li>浮点型 real、float、double</li>
<li>数值型 numeric (p [,d])</li>
</ul>
</li>
<li>日期／时间型：<ul>
<li>DateTime</li>
</ul>
</li>
<li>文本和图像型<ul>
<li>Text：存放大量文本数据。在SQLServer中，Text对象实际为一指针</li>
<li>Image：存放图形数据</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>数据操纵语言（DML，Data Manipulation Language）</p>
<ul>
<li>数据操纵语言是指用来查询、添加、修改和删除数据库中数据的语句，这些语句包括SELECT、INSERT、UPDATE、DELETE等。在默认情况下，只有sysadmin、dbcreator、db_owner或db_datawriter等角色的成员才有权利执行数据操纵语言。</li>
</ul>
</li>
<li><p>数据控制语言（DCL，Data Control Language）</p>
<ul>
<li>数据控制语言（DCL）是用来设置或者更改数据库用户或角色权限的语句，这些语句包括GRANT、REVOKE 、DENY等语句，在默认状态下，只有sysadmin、dbcreator、db_owner或db_securityadmin等角色的成员才有权利执行数据控制语言。
        <h3 id="SQL语句"   >
          <a href="#SQL语句" class="heading-link"><i class="fas fa-link"></i></a>SQL语句</h3>
      </li>
</ul>
</li>
<li><p>建立表结构 Create</p>
<ul>
<li>定义基本表的语句格式：</li>
<li>CREATE TABLE &lt;表名&gt;(&lt;列定义&gt;[{,&lt;列定义&gt;,&lt;表约束&gt;}])</li>
<li>表名：</li>
<li>列定义：列名、列数据类型、长度、是否允许空值等。</li>
<li>定义完整性约束：列约束和表约束</li>
<li>[CONSTRAINT&lt;约束名&gt;] &lt;约束定义&gt;</li>
</ul>
</li>
<li><p>删除表结构 Drop</p>
<ul>
<li>用SQL删除关系（表）<ul>
<li>将整个关系模式（表结构）彻底删除</li>
<li>表中的数据也将被删除</li>
</ul>
</li>
</ul>
</li>
<li><p>修改表结构 Alter</p>
<ul>
<li>增加表中的属性<ul>
<li>向已经存在的表中添加属性</li>
<li>allow null （新添加的属性要允许为空）</li>
<li>已有的元组中该属性的值被置为Null</li>
</ul>
</li>
<li>修改表中的某属性(某列)<ul>
<li>修改属性类型或精度</li>
</ul>
</li>
<li>删除表中的某属性(某列)<ul>
<li>去除属性及相应的数据</li>
</ul>
</li>
</ul>
</li>
<li><p>向表中添加数据(Insert)</p>
<ul>
<li>数据添加<ul>
<li>用SQL的插入语句，向数据库表中添加数据</li>
<li>按关系模式的属性顺序</li>
<li>按指定的属性顺序，也可以只添加部分属性（非Null属性为必需）</li>
</ul>
</li>
</ul>
</li>
<li><p>数据删除（Delete）</p>
<ul>
<li>只能对整个元组操作，不能只删除某些属性上的值</li>
<li>只能对一个关系起作用，若要从多个关系中删除元组，则必须对每个关系分别执行删除命令</li>
<li>删除单个元组</li>
<li>删除多个元组</li>
<li>删除整个关系中的所有数据</li>
</ul>
</li>
<li><p>数据更新（Update）</p>
<ul>
<li>改变符合条件的某个（某些）元组的属性值</li>
</ul>
</li>
<li><p>数据查询（Select）</p>
<ul>
<li>数据查询是数据库应用的核心功能</li>
<li>Select子句——重复元组<ul>
<li>SQL具有包的特性</li>
<li>Select 子句的缺省情况是保留重复元组（ ALL ），可用 Distinct 去除重复元组</li>
<li>去除重复元组:费时</li>
<li>需要临时表的支持</li>
</ul>
</li>
<li>Select子句—— *与属性列表<ul>
<li>星号 * 表示所有属性<ul>
<li>星号 * ：按关系模式中属性的顺序排列</li>
<li>显式列出属性名：按用户顺序排列</li>
</ul>
</li>
</ul>
</li>
<li>Select子句——更名<ul>
<li>为结果集中的某个属性改名</li>
<li>使结果集更具可读性</li>
</ul>
</li>
<li>Where 子句<ul>
<li>查询满足指定条件的元组可以通过Where子句来实现</li>
<li>使where子句中的逻辑表达式返回True值的元组，是符合要求的元组，将被选择出来</li>
<li>Where 子句——运算符<ul>
<li>比较：&lt;、&lt;=、&gt;、&gt;=、=、&lt;&gt; 等</li>
<li>确定范围：<ul>
<li>Between  A  and  B、Not Between A and B</li>
</ul>
</li>
<li>确定集合：IN、NOT IN</li>
<li>字符匹配：LIKE，NOT LIKE</li>
<li>空值：IS NULL、IS NOT NULL</li>
<li>多重条件：AND、OR、NOT</li>
</ul>
</li>
<li>Where 子句——Like<ul>
<li>字符匹配：Like、Not Like</li>
<li>通配符</li>
<li>% —— 匹配任意字符串</li>
<li>_   —— 匹配任意一个字符</li>
<li>大小写敏感</li>
</ul>
</li>
<li>Where 子句——转义符 escape </li>
</ul>
</li>
<li>From 子句<ul>
<li>列出将被查询的关系（表）</li>
<li>From 子句——元组变量<ul>
<li>为 From 子句中的关系定义元组变量</li>
<li>方便关系名的引用</li>
</ul>
</li>
<li>连接子句<ul>
<li>内连接<ul>
<li>内连接是指包括符合条件的每个表的记录，也称之为全记录操作。</li>
</ul>
</li>
<li>外连接<ul>
<li>外连接是指把两个表分为左右两个表。右外连接是指连接满足条件右侧表的全部记录。左外连接是指连接满足条件左侧表的全部记录。全外连接是指连接满足条件表的全部记录。</li>
<li>左外连接</li>
<li>右外连接</li>
<li>全外连接</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Order By子句<ul>
<li>指定结果集中元组的排列次序</li>
<li>耗时</li>
<li>ASC升序（缺省）、DESC降序</li>
</ul>
</li>
<li>子查询（Subquery ）<ul>
<li>子查询是嵌套在另一查询中的 Select-From-Where 表达式（Where/Having）</li>
<li>SQL允许多层嵌套，由内而外地进行分析，子查询的结果作为父查询的查找条件</li>
<li>可以用多个简单查询来构成复杂查询，以增强SQL的查询能力</li>
<li>子查询中不使用 Order By 子句，Order By子句只能对最终查询结果进行排序</li>
<li>子查询——单值比较<ul>
<li>返回单值的子查询，只返回一行一列</li>
<li>父查询与单值子查询之间用比较运算符进行连接<ul>
<li>运算符：&gt;、&gt;=、=、&lt;=、&lt;、 &lt;&gt;</li>
</ul>
</li>
</ul>
</li>
<li>子查询——多值<ul>
<li>子查询返回多行一列</li>
<li>运算符：In、All、Some(或Any)、Exists<ul>
<li>子查询——多值成员In<ul>
<li>若值与子查询返回集中的某一个相等，则返回true<ul>
<li>IN 被用来测试多值中的成员</li>
</ul>
</li>
</ul>
</li>
<li>子查询——多值比较 ALL<ul>
<li>父查询与多值子查询之间的比较用All来连接</li>
<li>值s比子查询返回集R中的每个都大时，s&gt;All R 为True </li>
<li>All表示所有</li>
<li><blockquote>
<p>all、&lt; all、&lt;=all、&gt;=all、&lt;&gt; all</p>
</blockquote>
</li>
<li>&lt;&gt; all 等价于 not in</li>
</ul>
</li>
<li>子查询——多值比较Some/Any<ul>
<li>父查询与多值子查询之间的比较需用Some/Any来连接</li>
<li>值s比子查询返回集R中的某一个都大时返回 Ture<ul>
<li>s &gt; Some R为True  或 </li>
<li>s &gt; Any R为True </li>
</ul>
</li>
<li>Some(早期用Any)表示某一个（任意一个）</li>
<li><blockquote>
<p>some、&lt; some、&lt;=some、&gt;=some、&lt;&gt; some</p>
</blockquote>
</li>
<li>= some 等价于 in、&lt;&gt; some 不等价于 not in</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>子查询——存在判断Exists<ul>
<li>Exists + 子查询用来判断该子查询是否返回元组</li>
<li>当子查询的结果集非空时，Exists为True</li>
<li>当子查询的结果集为空时，Exists为False</li>
<li>不关心子查询的具体内容，因此用 Select *</li>
<li>具有外部引用的子查询，称为相关子查询（Correlated Queries）</li>
<li>外层元组的属性作为内层子查询的条件</li>
</ul>
</li>
</ul>
</li>
<li>聚合函数<ul>
<li>把一列中的值进行聚合运算，返回单值的函数</li>
<li>五个预定义的聚合函数<ul>
<li>平均值：Avg( )</li>
<li>总和：  Sum( )</li>
<li>最小值：Min( )</li>
<li>最大值：Max( )</li>
<li>计数：  Count( )  返回所选列中不为NULL的数</li>
</ul>
</li>
<li>Group By<ul>
<li>将查询结果集按某一列或多列的值分组，值相等的为一组，一个分组以一个元组的形式出现</li>
<li>只有出现在Group By子句中的属性，才可出现在Select子句中</li>
</ul>
</li>
<li>Having<ul>
<li>针对聚合函数的结果值进行筛选（选择），它作用于分组计算结果集</li>
<li>跟在Group By子句的后面。</li>
</ul>
</li>
<li>Having 与 Where的区别<ul>
<li>Where 决定哪些元组被选择参加运算，作用于关系中的元组</li>
<li>Having 决定哪些分组符合要求，作用于分组</li>
<li>聚合函数的条件关系必须用Having，Where中不应出现聚合函数</li>
</ul>
</li>
<li>聚合函数对Null的处理<ul>
<li>Count：不计</li>
<li>Sum：不将其计入</li>
<li>Avg：具有 Null 的元组不参与</li>
<li>Max / Min：不参与
        <h3 id="视-图-VIEW"   >
          <a href="#视-图-VIEW" class="heading-link"><i class="fas fa-link"></i></a>视     图   (VIEW)</h3>
      </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>视图是从一个或者多个表或视图中导出的表，其结构和数据是建立在对表的查询基础上的。和真实的表一样，视图也包括几个被定义的数据列和多个数据行，但从本质上讲，这些数据列和数据行来源于其所引用的表。因此，视图不是真实存在的基础表而是一个虚拟表，视图所对应的数据并不实际地以视图结构存储在数据库中，而是存储在视图所引用的表中。</p>
</li>
<li><p>创建视图</p>
</li>
<li><p>视图的更新</p>

        <h3 id="索引"   >
          <a href="#索引" class="heading-link"><i class="fas fa-link"></i></a>索引</h3>
      </li>
<li><p>数据库中的索引与书籍中的索引类似，在一本书中，利用索引可以快速查找所需信息，无须阅读整本书。在数据库中，索引使数据库程序无须对整个表进行扫描，就可以在其中找到所需数据。书中的索引是一个词语列表，其中注明了包含各个词的页码。而数据库中的索引是某个表中一列或者若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单</p>
</li>
<li><p>索引的作用</p>
<ul>
<li>通过创建唯一索引，可以保证数据记录的唯一性。</li>
<li>可以大大加快数据检索速度。</li>
<li>可以加速表与表之间的连接，这一点在实现数据的参照完整性方面有特别的意义。</li>
<li>在使用ORDER BY和GROUP BY子句中进行检索数据时，可以显著减少查询中分组和排序的时间。</li>
<li>使用索引可以在检索数据的过程中使用优化隐藏器，提高系统性能</li>
</ul>
</li>
<li><p>聚集索引与非聚集索引</p>
<ul>
<li>聚集索引对表的物理数据页中的数据按列进行排序，然后再重新存储到磁盘上，即聚集索引与数据是混为一体的，它的叶节点中存储的是实际的数据</li>
<li>非聚集索引具有完全独立于数据行的结构，使用非聚集索引不用将物理数据页中的数据按列排序。非聚集索引的叶节点存储了组成非聚集索引的关键字值和行定位器</li>
</ul>
</li>
<li><p>创建索引</p>

        <h3 id="约束"   >
          <a href="#约束" class="heading-link"><i class="fas fa-link"></i></a>约束</h3>
      </li>
<li><p>主键约束（primary key constraint）</p>
</li>
<li><p>唯一性约束（unique constraint）</p>
</li>
<li><p>检查约束（check constraint）</p>
</li>
<li><p>缺省约束（default constraint）</p>
</li>
<li><p>外部键约束（foreign key constraint）</p>

        <h3 id="SQL-SERVER权限管理"   >
          <a href="#SQL-SERVER权限管理" class="heading-link"><i class="fas fa-link"></i></a>SQL SERVER权限管理</h3>
      </li>
<li><p>SQL Server权限管理策略 </p>
<ul>
<li>安全帐户认证 <ul>
<li>安全帐户认证是用来确认登录SQL Server的用户的登录帐号和密码的正确性，由此来验证其是否具有连接SQL Server的权限。 SQL Server 2000提供了两种确认用户的认证模式：<ul>
<li>（一）Windows NT认证模式。<ul>
<li>SQL Server数据库系统通常运行在Windows NT服务器平台上，而NT作为网络操作系统，本身就具备管理登录、验证用户合法性的能力，因此Windows NT认证模式正是利用了这一用户安全性和帐号管理的机制，允许SQL Server也可以使用NT的用户名和口令。在这种模式下，用户只需要通过Windows NT的认证，就可以连接到SQL Server，而SQL Server本身也就不需要管理一套登录数据。</li>
</ul>
</li>
<li>（二）混合认证模式。<ul>
<li>混合认证模式允许用户使用Windows NT安全性或SQL Server安全性连接到SQL Server，这就意味着用户可以使用他的帐号登录到Windows NT，或者使用他的登录名登录到SQL Server系统。NT的用户既可以使用NT认证，也可以使用SQL Server认证</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>访问许可确认 <ul>
<li>但是通过认证阶段并不代表用户能够访问SQL Server中的数据，同时他还必须通过许可确认。用户只有在具有访问数据库的权限之后，才能够对服务器上的数据库进行权限许可下的各种操作，这种用户访问数据库权限的设置是通过用户帐号来实现的。</li>
</ul>
</li>
</ul>
</li>
<li><p>用户权限管理</p>
<ul>
<li>服务器登录帐号和用户帐号管理 <ul>
<li>1.利用企业管理器创建、管理SQL Server登录帐号<ul>
<li>（１）打开企业管理器，单击需要登录的服务器左边的“+”号，然后展开安全性文件夹。 </li>
<li>（２）用右键单击登录（login）图标，从快捷菜单中选择新建登录（new login）选项，则出现SQL Server登录属性—新建登录对话框，如图6-2所示。</li>
<li>（3）在名称编辑框中输入登录名，在身份验证选项栏中选择新建的用户帐号是Windows NT认证模式，还是SQL Server认证模式。 </li>
<li>（４）选择服务器角色页框。在服务器角色列表框中，列出了系统的固定服务器角色。 </li>
<li>（５）选择用户映射页框。上面的列表框列出了该帐号可以访问的数据库，单击数据库左边的复选框，表示该用户可以访问相应的数据库以及该帐号在数据库中的用户名。 </li>
<li>（６）设置完成后，单击“确定”按钮即可完成登录帐号的创建。 </li>
</ul>
</li>
<li>使用SQL 语句创建登录帐号</li>
<li>2.用户帐号管理 <ul>
<li>在数据库中，一个用户或工作组取得合法的登录帐号，只表明该帐号通过了Windows NT认证或者SQL Server认证，但不能表明其可以对数据库数据和数据库对象进行某种或者某些操作，只有当他同时拥有了用户权限后，才能够访问数据库。 </li>
<li>利用企业管理器可以授予SQL Server登录访问数据库的许可权限。使用它可创建一个新数据库用户帐号 </li>
</ul>
</li>
</ul>
</li>
<li>许可（权限）管理 <ul>
<li>许可用来指定授权用户可以使用的数据库对象和这些授权用户可以对这些数据库对象执行的操作。用户在登录到SQL Server之后，其用户帐号所归属的NT组或角色所被赋予的许可（权限）决定了该用户能够对哪些数据库对象执行哪种操作以及能够访问、修改哪些数据。在每个数据库中用户的许可独立于用户帐号和用户在数据库中的角色，每个数据库都有自己独立的许可系统，在SQL Server中包括三种类型的许可：即对象许可、语句许可和预定义许可。 <ul>
<li>三种许可类型<ul>
<li>1、对象许可<ul>
<li>表示对特定的数据库对象，即表、视图、字段和存储过程的操作许可，它决定了能对表、视图等数据库对象执行哪些操作。</li>
</ul>
</li>
<li>2、语句许可<ul>
<li>表示对数据库的操作许可，也就是说，创建数据库或者创建数据库中的其它内容所需要的许可类型称为语句许可。</li>
</ul>
</li>
<li>3、预定义许可<ul>
<li>是指系统安装以后有些用户和角色不必授权就有的许可。 </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>角色管理<ul>
<li>角色是SQL Server 7.0版本引进的新概念，它代替了以前版本中组的概念。利用角色，SQL Server管理者可以将某些用户设置为某一角色，这样只对角色进行权限设置便可以实现对所有用户权限的设置，大大减少了管理员的工作量。SQL Server提供了用户通常管理工作的预定义服务器角色和数据库角色。<ul>
<li>1、服务器角色<ul>
<li>服务器角色是指根据SQL Server的管理任务，以及这些任务相对的重要性等级来把具有SQL Server管理职能的用户划分为不同的用户组，每一组所具有的管理SQL Server的权限都是SQL Server内置的，即不能对其进行添加、修改和删除，只能向其中加入用户或者其他角色。 </li>
<li>几种常用的固定服务器角色 <ul>
<li>系统管理员：拥有SQL Server所有的权限许可。</li>
<li>服务器管理员：管理SQL Server服务器端的设置。</li>
<li>磁盘管理员：管理磁盘文件。</li>
<li>进程管理员：管理SQL Server系统进程。</li>
<li>安全管理员：管理和审核SQL Server系统登录。</li>
<li>安装管理员：增加、删除连接服务器，建立数据库复制以及管理扩展存储过程。</li>
<li>数据库创建者：创建数据库，并对数据库进行修改。</li>
</ul>
</li>
</ul>
</li>
<li>2、数据库角色 <ul>
<li>数据库角色是为某一用户或某一组用户授予不同级别的管理或访问数据库以及数据库对象的权限，这些权限是数据库专有的，并且还可以使一个用户具有属于同一数据库的多个角色。SQL Server提供了两种类型的数据库角色：即固定的数据库角色和用户自定义的数据库角色。 </li>
<li>（１）固定的数据库角色<ul>
<li>public：维护全部默认许可。</li>
<li>db_owner：数据库的所有者，可以对所拥有的数据库执行任何操作。</li>
<li>db_accessadmin：可以增加或者删除数据库用户、工作组和角色。</li>
<li>db_addladmin：可以增加、删除和修改数据库中的任何对象。</li>
<li>db_securityadmin：执行语句许可和对象许可。</li>
<li>db_backupoperator：可以备份和恢复数据库。</li>
<li>db_datareader：能且仅能对数据库中的任何表执行select操作，从而读取所有表的信息。</li>
<li>db_datawriter：能够增加、修改和删除表中的数据，但不能进行select操作。</li>
<li>db_denydatareader：不能读取数据库中任何表中的数据。</li>
<li>db_denydatawriter：不能对数据库中的任何表执行增加、修改和删除数据操作。 </li>
</ul>
</li>
<li>（２）用户自定义角色 <ul>
<li>创建用户定义的数据库角色就是创建一组用户，这些用户具有相同的一组许可。如果一组用户需要执行在SQL Server中指定的一组操作并且不存在对应的Windows NT组，或者没有管理Windows NT用户帐号的许可，就可以在数据库中建立一个用户自定义的数据库角色。用户自定义的数据库角色有两种类型：即标准角色和应用程序角色。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Transaction_SQL 语句</p>
<ul>
<li>赋权语句——Grant</li>
<li>收回权限——Revoke </li>
<li>收回权限——Deny 
        <h2 id="查询优化"   >
          <a href="#查询优化" class="heading-link"><i class="fas fa-link"></i></a>查询优化</h2>
      
        <h3 id="概述-1"   >
          <a href="#概述-1" class="heading-link"><i class="fas fa-link"></i></a>概述</h3>
      </li>
</ul>
</li>
<li><p>关系系统和关系模型是两个密切相关而有不同的概念。支持关系模型的数据库管理系统称为关系系统。但是关系模型中并非每一部分都是同等重要的，所以我们不苛求完全支持关系模型的系统才能称为关系系统。因此，我们给出一个关系系统的最小要求以及分类的定义。 </p>
</li>
<li><p>关系系统的定义</p>
<ul>
<li>1.支持关系数据库（关系数据结构）<ul>
<li>从用户观点看，数据库由表构成，并且只有表这一种结构。</li>
</ul>
</li>
<li>2.支持选择、投影和（自然）连接运算，对这些运算不必要求定义任何物理存取路径 <ul>
<li>当然并不要求关系系统的选择、投影、连接运算和关系代数的相应运算完全一样，而只要求有等价的这三种运算功能就行。 
        <h3 id="查询优化-1"   >
          <a href="#查询优化-1" class="heading-link"><i class="fas fa-link"></i></a>查询优化</h3>
      </li>
</ul>
</li>
</ul>
</li>
<li><p>查询优化：对于给定的查询选择代价最小的操作序列，使查询过程既省时间，具有较高的效率，这就是所谓的查询优化。对于关系数据库系统，用户只要提出“做什么”，而由系统解决“怎么做”的问题。具体来说，是数据库管理系统中的查询处理程序自动实现查询优化。</p>
</li>
<li><p>关系查询优化是影响RDBMS性能的关键因素。关系系统的查询优化既是RDBMS实现的关键技术又是关系系统的优点所在。</p>
</li>
<li><p>查询优化的优点不仅在于用户不必考虑如何最好地表达查询以获得较好的效率，而且在于系统可以比用户程序的“优化”做得更好。 </p>
</li>
<li><p>查询优化的一般准则</p>
<ul>
<li>1.选择运算应尽可能先做。在优化策略中这是最重要、最基本的一条。它常常可使执行时节约几个数量级，因为选择运算一般使计算的中间结果大大变小</li>
<li>2.在执行连接前对关系适当地预处理。预处理方法主要有两种，在连接属性上建立索引和对关系排序 。</li>
<li>3.把投影运算和选择运算同时进行。如有若干投影和选择运算，并且它们都对同一个关系操作，则可以在扫描此关系的同时完成所有的这些运算以避免重复扫描关系。 </li>
<li>4.把投影同其前或其后的双目运算结合起来，没有必要为了去掉某些字段而扫描一遍关系</li>
<li>5.杷某些选择同在它前面要执行的笛卡尔积结合起来成为一个连接运算，连接特别是等值连接运算要比同样关系上的笛卡尔积省很多时间 </li>
<li>6.找出公共子表达式。
        <h2 id="关系数据库设计理论"   >
          <a href="#关系数据库设计理论" class="heading-link"><i class="fas fa-link"></i></a>关系数据库设计理论</h2>
      
        <h3 id="设计一个好的关系数据库系统，关键是要设计一个好的数据库模式（数据库逻辑设计问题）"   >
          <a href="#设计一个好的关系数据库系统，关键是要设计一个好的数据库模式（数据库逻辑设计问题）" class="heading-link"><i class="fas fa-link"></i></a>设计一个好的关系数据库系统，关键是要设计一个好的数据库模式（数据库逻辑设计问题）</h3>
      </li>
</ul>
</li>
</ul>

        <h3 id="数据库逻辑设计主要解决的问题"   >
          <a href="#数据库逻辑设计主要解决的问题" class="heading-link"><i class="fas fa-link"></i></a>数据库逻辑设计主要解决的问题</h3>
      <ul>
<li><p>关系数据库应该组织成几个关系模式</p>
</li>
<li><p>关系模式中包括哪些属性</p>

        <h3 id="“不好”的数据库设计"   >
          <a href="#“不好”的数据库设计" class="heading-link"><i class="fas fa-link"></i></a>“不好”的数据库设计</h3>
      </li>
<li><p>举例：为学校设计一个关系数据库</p>
</li>
<li><p>关系模式: UN(Sno,Cno,G,Sdept,MN)</p>
<ul>
<li>Sno:描述学生</li>
<li>Sdept:描述系名</li>
<li>MN:描述系主任</li>
<li>Cno:描述课程</li>
<li>G:描述学习成绩</li>
<li>根据对现实世界的分析,可得出:Sno,Cno是码</li>
<li>按照关系模式UN装入部分数据</li>
</ul>
</li>
<li></li>
<li><p>对数据库操作时,会出现以下问题</p>
<ul>
<li><ol>
<li>数据冗余(系主任名的存储次数)<ul>
<li>数据重复存储:浪费存储空间,数据库维护困难(更新异常)</li>
</ul>
</li>
</ol>
</li>
<li><ol start="2">
<li>插入异常(一个系刚成立)<ul>
<li>主码为空的记录不能存在与数据库,导致不能进行插入操作</li>
</ul>
</li>
</ol>
</li>
<li><ol start="3">
<li>删除异常(一个系的学生全部毕业)<ul>
<li>删除操作后,一些相关信息无法保存在数据库中</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>要消除以上的“弊病”,把上面的关系数据库模式分解为三个关系模式</p>
<ul>
<li>S(Sno,Sdept)</li>
<li>SG(Sno,Cno,G)</li>
<li>Dept(Sdept,MN)
        <h3 id="函数依赖"   >
          <a href="#函数依赖" class="heading-link"><i class="fas fa-link"></i></a>函数依赖</h3>
      </li>
</ul>
</li>
<li><p>类似于变量之间的单值函数关系</p>
</li>
<li><p>Y=F(X),其中自变量X的值,决定一个唯一的函数值Y</p>
</li>
<li><p>在一个关系模式里的属性,由于它在不同元组里属性值可能不同,由此可以把关系中的属性看作变量</p>
</li>
<li><p>一个属性与另一个属性在取值上可能存在制约关系</p>
</li>
<li><p>函数依赖就是属性间的逻辑依赖关系</p>
</li>
<li><p>定义1 设R(U)是一个关系模式,U是R的属性集合,X和Y是U的子集.对于R(U)的任何一个可能的关系r,如果r中不存在两个元组,它们在X上的属性值相同,而在Y上的属性值不同,则称X函数决定Y,或Y函数依赖于X,记作:X  Y.</p>
</li>
<li><p>X通常称为“决定因素”</p>
</li>
<li><p>几点说明</p>
<ul>
<li><ol>
<li>函数依赖是语义范畴的概念.它反映了一种语义完整性约束,只能根据语义来确定一个函数依赖.</li>
</ol>
</li>
<li><ol start="2">
<li>函数依赖是指关系R模式的所有关系元组均应满足的约束条件,而不是关系模式中的某个或某些元组满足的约束条件</li>
</ol>
</li>
<li><ol start="3">
<li>函数依赖与属性间的联系类型有关<ul>
<li>(1)若属性X和Y之间有“一对一”的联系,</li>
<li>(2)若属性X和Y之间有“多对一”的联系,</li>
<li>(3)若属性X和Y之间有“多对多”的联系,</li>
</ul>
</li>
</ol>
</li>
<li><ol start="4">
<li>如果X   Y,并且Y不是X的子集,则称X   Y是非平凡的函数依赖;如果Y是X的子集,则称X   Y是平凡的函数依赖;
        <h3 id="完全函数依赖与部分函数依赖"   >
          <a href="#完全函数依赖与部分函数依赖" class="heading-link"><i class="fas fa-link"></i></a>完全函数依赖与部分函数依赖</h3>
      </li>
</ol>
</li>
</ul>
</li>
<li><p>完全函数依赖</p>
</li>
<li><p>部分函数依赖</p>

        <h3 id="码的形式定义"   >
          <a href="#码的形式定义" class="heading-link"><i class="fas fa-link"></i></a>码的形式定义</h3>
      </li>
<li><p>候选码的两个性质</p>
<ul>
<li><ol>
<li>标识的唯一性: 对于R(U)中的每一元组,K的值确定后,该元组就相应确定了.</li>
</ol>
</li>
<li><ol start="2">
<li>无冗余性: K是属性组的情况下,K的任何一部分都不能唯一标识该元组(定义中的完全函数依赖的意义) 
        <h3 id="规范化"   >
          <a href="#规范化" class="heading-link"><i class="fas fa-link"></i></a>规范化</h3>
      </li>
</ol>
</li>
</ul>
</li>
<li><p>简介</p>
<ul>
<li>用几个简单的关系去取代原来结构复杂的关系的过程叫做关系规范化.</li>
<li>规范化理论是研究如何把一个不好的关系模式转化为好的关系模式的理论</li>
<li>规范化理论是E.E.Codd在1971年首先提出的</li>
<li>规范化理论是数据库设计过程中的一个非常有用的辅助工具</li>
</ul>
</li>
<li><p>范式</p>
<ul>
<li>简介<ul>
<li>规范化理论是围绕着范式建立的.</li>
<li>满足不同程度要求的约束集则称为不同的范式.</li>
<li>如果一个关系满足某个指定的约束集,则称它属于某个特定的范式.</li>
<li>较高层次的范式比较低层次的范式具有“更合乎要求的性质”</li>
<li>一个低一级范式的关系模式,通过投影运算可以转化为若干个高一级范式的关系模式的集合,这个过程叫做规范化.</li>
<li>如果一个关系满足某个范式要求,则它也会满足较其级别低的所有范式的要求</li>
</ul>
</li>
<li>范式层次</li>
<li>第一范式(1NF)<ul>
<li>定义5: 在关系模式R中的每一个具体关系r中,如果每个属性值都是不可再分的最小数据单位,则称R是第一范式的关系,记作R∈1NF.</li>
<li>数据库理论研究的是规范化关系.</li>
<li>1NF规范化: 把非规范化关系规范提高到1NF关系模式的集合.</li>
</ul>
</li>
<li>第二范式(2NF)<ul>
<li>定义6: 若关系模式R∈1NF,且每个非主属性都完全依赖于R的任意候选码,则关系模式R属于第二范式,记作R ∈2NF.</li>
<li>2NF规范化是把1NF关系模式规范提高到变成2NF关系模式的集合.</li>
<li>从1NF中消除非主属性对候选码的部分函数依赖,则获得2NF关系.</li>
<li>举例:UN(Sno,Cno,G,SDN,MN)</li>
</ul>
</li>
<li>第三范式(3NF)<ul>
<li>定义7: 若关系模式R∈2NF,且每个非主属性都不传递依赖于R的任意候选码,则R∈3NF.</li>
<li>从2NF关系中,消除非主属性对码的传递依赖函数而获得3NF关系</li>
<li>R∈3NF,则每个非主属性既不部分依赖,也不传递依赖于R的任何候选码.</li>
<li>3NF的规范化</li>
</ul>
</li>
<li>BCNF范式<ul>
<li>3NF的不完善性<ul>
<li>定义8: 若R∈1NF,且R中每个决定因素都是候选码,则R ∈BCNF.</li>
<li>满足BCNF的关系将消除任何属性对候选码的部分依赖与传递依赖</li>
<li>应用BCNF定义时,可直接判断1NF是否属于BCNF</li>
<li>BCNF规范化
        <h2 id="数据库设计"   >
          <a href="#数据库设计" class="heading-link"><i class="fas fa-link"></i></a>数据库设计</h2>
      
        <h3 id="概述-2"   >
          <a href="#概述-2" class="heading-link"><i class="fas fa-link"></i></a>概述</h3>
      </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>数据库技术是信息资源管理最有效的手段。数据库设计是指对于一个给定的应用环境，构造最优的数据库模式，建立数据库极其应用系统，有效存储数据，满足用户信息要求和处理要求。 </p>

        <h3 id="数据库设计的步骤"   >
          <a href="#数据库设计的步骤" class="heading-link"><i class="fas fa-link"></i></a>数据库设计的步骤</h3>
      </li>
<li><p>⒈需求分析阶段 </p>
<ul>
<li>收集和分析用户需求，结果得到数据字典描述的数据需求。 </li>
<li>常用的调查方法<ul>
<li>⑴跟班作业 </li>
<li>⑵开调查会</li>
<li>⑶请专人介绍</li>
<li>⑷询问对某些调查中的问题，可以找专人询问。</li>
<li>⑸设计调查表请用户填写</li>
<li>⑹查阅记录</li>
</ul>
</li>
</ul>
</li>
<li><p>⒉概念结构设计阶段</p>
<ul>
<li>通过对用户需求进行综合、归纳与抽象，形成一个独立于具体DBMS的概念模型，可以用E-R图表示。这是数据库设计的关键</li>
</ul>
</li>
<li><p>⒊逻辑结构设计阶段</p>
<ul>
<li>将概念结构转换为某个DBMS所支持的数据模型（例如关系模型），并对其进行优化（例如使用范式理论）</li>
</ul>
</li>
<li><p>⒋数据库物理设计阶段</p>
<ul>
<li>为逻辑数据模型选取一个最适合应用环境的物理结构（包括存储结构和存取方法）。</li>
</ul>
</li>
<li><p>⒌数据库实施阶段</p>
<ul>
<li>运用DBMS提供的数据语言（例如SQL）及其宿主语言（例如C），根据逻辑设计和物理设计的结果建立数据库，编制与调试应用程序，组织数据入库，并进行试运行</li>
</ul>
</li>
<li><p>⒍数据库运行和维护阶段</p>
<ul>
<li>数据库应用系统经过试运行后即可投入正式运行。在数据库系统运行过程中必须不断地对其进行评价、调整与修改
        <h3 id="数据字典"   >
          <a href="#数据字典" class="heading-link"><i class="fas fa-link"></i></a>数据字典</h3>
      </li>
</ul>
</li>
<li><p>对数据库设计来讲，数据字典是进行数据收集和数据分析所获得的主要成果。数据字典是各类数据描述的集合。 </p>
</li>
<li><p>数据字典通常包括数据项、数据结构、数据流、数据存储和处理过程五个部分。 </p>
<ul>
<li>数据项是不可再分的数据单位</li>
<li>数据结构反映了数据之间的组合关系。一个数据结构可以由若干个数据项组成，也可以由若干个数据结构组成，或由若干个数据项和数据结构混合组成</li>
<li>数据流是数据结构在系统内传输的路径</li>
<li>数据存储是数据结构停留或保存的地方，也是数据流的来源和去向之一</li>
<li>处理过程描述＝｛处理过程名，说明，输入:｛数据流｝，输出:｛数据流｝, 处理:｛简要说明｝｝
        <h3 id="设计概念结构通常有四类方法"   >
          <a href="#设计概念结构通常有四类方法" class="heading-link"><i class="fas fa-link"></i></a>设计概念结构通常有四类方法</h3>
      </li>
</ul>
</li>
<li><p>自顶向下</p>
<ul>
<li>即首先定义全局概念结构的框架，然后逐步细化。</li>
</ul>
</li>
<li><p>自底向上 </p>
<ul>
<li>即首先定义各局部应用的概念结构，然后将它们集成起来，得到全局概念结构。这是最经常采用的策略。即自顶向下地进行需求分析，然后再自底向上地设计概念结构</li>
</ul>
</li>
<li><p>逐步扩张 </p>
<ul>
<li>首先定义最重要的核心概念结构，然后向外扩充，以滚雪球的方式逐步生成其他概念结构，直至总体概念结构</li>
</ul>
</li>
<li><p>混合策略</p>
<ul>
<li>即将自顶向下和自底向上相结合，用自顶向下策略设计一个全局概念结构的框架，以它为骨架集成由自底向上策略中设计的各局部概念结构
        <h3 id="E-R图"   >
          <a href="#E-R图" class="heading-link"><i class="fas fa-link"></i></a>E-R图</h3>
      </li>
</ul>
</li>
<li><p>E-R方法是抽象和描述现实世界的有力工具</p>
</li>
<li><p>要点</p>
<ul>
<li>使用长方形来表示实体型，框内写上实体名</li>
<li>椭圆型表示实体的属性，并用无向边把实体和属性连接起来。</li>
<li>用菱形表示实体间的联系，菱形框内写上联系名，用无向边把菱形分别与有关实体相连接，在无向边旁标上联系的类型，若实体之间联系也具有属性，则把属性和菱形也用无向边连接上。</li>
</ul>
</li>
<li><p>E-R图之间的冲突主要有三类</p>
<ul>
<li>属性冲突 <ul>
<li>(1) 属性域冲突，即属性值的类型、取值范围或取值集合不同。 </li>
<li>(2) 属性取值单位冲突</li>
</ul>
</li>
<li>命名冲突<ul>
<li>(1) 同名异义</li>
<li>(2) 异名同义（一义多名）</li>
</ul>
</li>
<li>结构冲突 <ul>
<li>(1) 同一对象在不同应用中具有不同的抽象。例如“教材”在某一局部应用中被当作实体，而在另一局部应用中则被当作属性</li>
<li>(2) 同一实体在不同局部视图中所包含的属性不完全相同，或者属性的排列次序不完全相同</li>
<li>(3) 实体之间的联系在不同局部视图中呈现不同的类型。例如实体E1与E2在局部应用A中是多对多联系，而在局部应用B中是一对多联系；又如在局部应用X中E1与E2发生联系，而在局部应用Y中E1、E2、E3三者之间有联系
        <h3 id="逻辑结构设计阶段"   >
          <a href="#逻辑结构设计阶段" class="heading-link"><i class="fas fa-link"></i></a>逻辑结构设计阶段</h3>
      </li>
</ul>
</li>
</ul>
</li>
<li><p>⒈一个实体型转换为一个关系模式。实体的属性就是关系的属性。实体的码就是关系的码。</p>
</li>
<li><p>⒉一个m:n联系转换为一个关系模式。与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性。而关系的码为各实体码的组合。</p>
</li>
<li><p>⒊一个1:n联系可以转换为一个独立的关系模式，也可以与n端对应的关系模式合并。如果转换为一个独立的关系模式，则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性，而关系的码为n端实体的码。</p>
</li>
<li><p>⒋一个1:1联系可以转换为一个独立的关系模式，也可以与任意一端对应的关系模式合并。如果转换为一个独立的关系模式，则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性，每个实体的码均是该关系的候选码。如果与某一端对应的关系模式合并，则需要在该关系模式的属性中加入另一个关系模式的码和联系本身的属性。</p>
</li>
<li><p>⒌三个或三个以上实体间的一个多元联系转换为一个关系模式。与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性。而关系的码为各实体码的组合。</p>
</li>
<li><ol start="6">
<li>具有相同码的关系模式可合并。
        <h3 id="数据模型的优化"   >
          <a href="#数据模型的优化" class="heading-link"><i class="fas fa-link"></i></a>数据模型的优化</h3>
      </li>
</ol>
</li>
<li><p>确定数据依赖</p>
</li>
<li><p>对于各个关系模式之间的数据依赖进行极小化处理，消除冗余的联系。</p>
</li>
<li><p>按照数据依赖的理论对关系模式逐一进行分析，考查是否存在部分函数依赖、传递函数依赖、多值依赖等，确定各关系模式分别属于第几范式。</p>
</li>
<li><p>按照需求分析阶段得到的各种应用对数据处理的要求，分析对于这样的应用环境这些模式是否合适，确定是否要对它们进行合并或分解。 </p>
</li>
<li><p>对关系模式进行必要的分解。</p>

        <h3 id="设计用户子模式"   >
          <a href="#设计用户子模式" class="heading-link"><i class="fas fa-link"></i></a>设计用户子模式</h3>
      </li>
<li><p>(1) 使用更符合用户习惯的别名 </p>
</li>
<li><p>(2) 针对不同级别的用户定义不同的视图，以满足系统对安全性的要求</p>
</li>
<li><p>(3) 简化用户对系统的使用</p>

        <h3 id="数据库物理设计"   >
          <a href="#数据库物理设计" class="heading-link"><i class="fas fa-link"></i></a>数据库物理设计</h3>
      </li>
<li><p>确定数据库存储结构时要综合考虑存取时间、存储空间利用率和维护代价三方面的因素。这三个方面常常是相互矛盾的。</p>
</li>
<li><p>为了提高系统性能，数据应该根据应用情况将易变部分与稳定部分、经常存取部分和存取频率较低部分分开存放</p>

        <h2 id="数据库恢复技术"   >
          <a href="#数据库恢复技术" class="heading-link"><i class="fas fa-link"></i></a>数据库恢复技术</h2>
      
        <h3 id="什么是事务"   >
          <a href="#什么是事务" class="heading-link"><i class="fas fa-link"></i></a>什么是事务</h3>
      </li>
<li><p>事务(Transaction)是用户定义的一个数据库操作序列，这些操作要么全做，要么全不做，是一个不可分割的工作单位</p>
</li>
<li><p>事务和程序是两个概念</p>
<ul>
<li>在关系数据库中，一个事务可以是一条SQL语句，一组SQL语句或整个程序</li>
<li>一个应用程序通常包含多个事务</li>
</ul>
</li>
<li><p>事务是恢复和并发控制的基本单位</p>

        <h3 id="事务结束"   >
          <a href="#事务结束" class="heading-link"><i class="fas fa-link"></i></a>事务结束</h3>
      </li>
<li><p>COMMIT</p>
<ul>
<li>事务正常结束   </li>
<li>提交事务的所有操作（读+更新）</li>
<li>事务中所有对数据库的更新永久生效</li>
</ul>
</li>
<li><p>ROLLBACK</p>
<ul>
<li>事务异常终止<ul>
<li>事务运行的过程中发生了故障，不能继续执行</li>
<li>回滚事务的所有更新操作</li>
<li>事务滚回到开始时的状态
        <h3 id="事务的特性-ACID特性"   >
          <a href="#事务的特性-ACID特性" class="heading-link"><i class="fas fa-link"></i></a>事务的特性(ACID特性)</h3>
      </li>
</ul>
</li>
</ul>
</li>
<li><p>原子性（Atomicity）</p>
<ul>
<li>事务是数据库的逻辑工作单位</li>
<li>事务中包括的诸操作要么都做，要么都不做</li>
</ul>
</li>
<li><p>一致性（Consistency）</p>
<ul>
<li>事务执行的结果必须是使数据库从一个   一致性状态变到另一个一致性状态</li>
<li>一致性状态：<ul>
<li>数据库中只包含成功事务提交的结果</li>
</ul>
</li>
<li>不一致状态：<ul>
<li>数据库中包含失败事务的结果</li>
</ul>
</li>
</ul>
</li>
<li><p>隔离性（Isolation）</p>
<ul>
<li><p>对并发执行而言一个事务的执行不能被其他事务干扰</p>
</li>
<li><p>一个事务内部的操作及使用的数据对其他并发事务是隔离的</p>
</li>
<li><p>并发执行的各个事务之间不能互相干扰</p>
</li>
</ul>
</li>
<li><p>持续性（Durability ）</p>
<ul>
<li>持续性也称永久性（Permanence）</li>
<li>一个事务一旦提交，它对数据库中数据的改变就应该是永久性的。</li>
<li>接下来的其他操作或故障不应该对其执行结果有任何影响。
        <h3 id="故障"   >
          <a href="#故障" class="heading-link"><i class="fas fa-link"></i></a>故障</h3>
      </li>
</ul>
</li>
<li><p>故障原因</p>
<ul>
<li>计算机硬件故障</li>
<li>系统软件和应用软件的错误</li>
<li>操作员的失误</li>
<li>恶意的破坏</li>
</ul>
</li>
<li><p>故障的影响</p>
<ul>
<li>运行事务非正常中断</li>
<li>破坏数据库</li>
</ul>
</li>
<li><p>故障的种类</p>
<ul>
<li>事务故障</li>
<li>系统故障</li>
<li>介质故障</li>
<li>计算机病毒
        <h3 id="恢复操作的基本原理"   >
          <a href="#恢复操作的基本原理" class="heading-link"><i class="fas fa-link"></i></a>恢复操作的基本原理</h3>
      </li>
</ul>
</li>
<li><p>恢复操作的基本原理：冗余</p>
</li>
<li><p>利用存储在系统其它地方的冗余数据来重建数据库中已被破坏或不正确的那部分数据</p>

        <h3 id="恢复的实现技术"   >
          <a href="#恢复的实现技术" class="heading-link"><i class="fas fa-link"></i></a>恢复的实现技术</h3>
      </li>
<li><p>数据转储（backup）</p>
</li>
<li><p>登录日志文件（logging）</p>

        <h2 id="并发控制"   >
          <a href="#并发控制" class="heading-link"><i class="fas fa-link"></i></a>并发控制</h2>
      
        <h3 id="多事务执行方式"   >
          <a href="#多事务执行方式" class="heading-link"><i class="fas fa-link"></i></a>多事务执行方式</h3>
      </li>
<li><p>(1)事务串行执行</p>
<ul>
<li>每个时刻只有一个事务运行，其他事务必须等到这个事务结束以后方能运行</li>
<li>不能充分利用系统资源，发挥数据库共享资源的特点</li>
</ul>
</li>
<li><p>(2)交叉并发方式（interleaved concurrency）</p>
<ul>
<li>事务的并行执行是这些并行事务的并行操作轮流交叉运行</li>
<li>是单处理机系统中的并发方式，能够减少处理机的空闲时间，提高系统的效率</li>
</ul>
</li>
<li><p>(3)同时并发方式（simultaneous  concurrency）</p>
<ul>
<li>多处理机系统中，每个处理机可以运行一个事务，多个处理机可以同时运行多个事务，实现多个事务真正的并行运行</li>
<li>最理想的并发方式，但受制于硬件环境</li>
<li>更复杂的并发方式机制
        <h3 id="事务并发执行带来的问题"   >
          <a href="#事务并发执行带来的问题" class="heading-link"><i class="fas fa-link"></i></a>事务并发执行带来的问题</h3>
      </li>
</ul>
</li>
<li><p>可能会存取和存储不正确的数据，破坏事务的隔离性和数据库的一致性</p>
</li>
<li><p>DBMS必须提供并发控制机制</p>
</li>
<li><p>并发控制机制是衡量一个DBMS性能的重要标志之一</p>

        <h3 id="并发控制机制的任务"   >
          <a href="#并发控制机制的任务" class="heading-link"><i class="fas fa-link"></i></a>并发控制机制的任务</h3>
      </li>
<li><p>对并发操作进行正确调度</p>
</li>
<li><p>保证事务的隔离性</p>
</li>
<li><p>保证数据库的一致性</p>

        <h3 id="并发操作带来的数据不一致性"   >
          <a href="#并发操作带来的数据不一致性" class="heading-link"><i class="fas fa-link"></i></a>并发操作带来的数据不一致性</h3>
      </li>
<li><p>丢失修改（lost update）</p>
<ul>
<li>丢失修改是指事务1与事务2从数据库中读入同一数据并修改</li>
<li>事务2的提交结果破坏了事务1提交的结果，导致事务1的修改被丢失。</li>
</ul>
</li>
<li><p>不可重复读（non-repeatable read）</p>
<ul>
<li>不可重复读是指事务1读取数据后，事务2执行更新操作，使事务1无法再现前一次读取结果。</li>
</ul>
</li>
<li><p>读“脏”数据（dirty read）</p>
<ul>
<li>事务1修改某一数据，并将其写回磁盘</li>
<li>事务2读取同一数据后</li>
<li>事务1由于某种原因被撤消，这时事务1已修改过的数据恢复原值</li>
<li>事务2读到的数据就与数据库中的数据不一致，</li>
<li>是不正确的数据，又称为“脏”数据。
        <h3 id="封锁"   >
          <a href="#封锁" class="heading-link"><i class="fas fa-link"></i></a>封锁</h3>
      </li>
</ul>
</li>
<li><p>什么是封锁</p>
<ul>
<li>封锁就是事务T在对某个数据对象（例如表、记录等）操作之前，先向系统发出请求，对其加锁</li>
<li>加锁后事务T就对该数据对象有了一定的控制，在事务T释放它的锁之前，其它的事务不能更新此数据对象。</li>
<li>封锁是实现并发控制的一个非常重要的技术</li>
</ul>
</li>
<li><p>基本封锁类型</p>
<ul>
<li>排它锁（eXclusive lock，简记为X锁）<ul>
<li>排它锁又称为写锁</li>
<li>若事务T对数据对象A加上X锁，则只允许T读取和修改A，其它任何事务都不能再对A加任何类型的锁，直到T释放A上的锁</li>
</ul>
</li>
<li>共享锁（Share lock，简记为S锁）<ul>
<li>共享锁又称为读锁</li>
<li>若事务T对数据对象A加上S锁，则其它事务只能再对A加S锁，而不能加X锁，直到T释放A上的S锁</li>
</ul>
</li>
</ul>
</li>
<li><p>基本锁的相容矩阵</p>
</li>
<li><p>封锁协议</p>
<ul>
<li>1级封锁协议<ul>
<li>事务T在修改数据R之前必须先对其加X锁，直到事务结束才释放</li>
<li>1级封锁协议可防止丢失修改</li>
<li>在1级封锁协议中，如果是读数据，不需要加锁的，所以它不能保证可重复读和不读“脏”数据。<ul>
<li>读“脏”数据</li>
<li>不可重复读</li>
</ul>
</li>
</ul>
</li>
<li>2级封锁协议<ul>
<li>1级封锁协议+事务T在读取数据R前必须先加S锁，读完后即可释放S锁</li>
<li>2级封锁协议可以防止丢失修改和读“脏”数据。</li>
<li>在2级封锁协议中，由于读完数据后即可释放S锁，所以它不能保证可重复读。</li>
</ul>
</li>
<li>3级封锁协议<ul>
<li>1级封锁协议 + 事务T在读取数据R之前必须先对其加S锁，直到事务结束才释放</li>
<li>3级封锁协议可防止丢失修改、读脏数据和不可重复读。</li>
</ul>
</li>
<li>三级协议的主要区别
        <h2 id="完整性约束"   >
          <a href="#完整性约束" class="heading-link"><i class="fas fa-link"></i></a>完整性约束</h2>
      
        <h3 id="完整性约束的分类"   >
          <a href="#完整性约束的分类" class="heading-link"><i class="fas fa-link"></i></a>完整性约束的分类</h3>
      </li>
</ul>
</li>
<li><p>静态列级约束</p>
<ul>
<li><ol>
<li>对数据类型的约束，包括数据的类型、长度单位、精度等</li>
</ol>
</li>
<li><ol start="2">
<li>对数据格式的约束 </li>
</ol>
</li>
<li><ol start="3">
<li>对取值范围或取值集合的约束</li>
</ol>
</li>
<li><ol start="4">
<li>对空值的约束</li>
</ol>
</li>
<li><ol start="5">
<li>其他约束 </li>
</ol>
</li>
</ul>
</li>
<li><p>静态元组约束</p>
<ul>
<li>一个元组是由若干个列值组成的，静态元组约束就是规定元组的各个列之间的约束关系</li>
</ul>
</li>
<li><p>静态关系约束</p>
<ul>
<li>在一个关系的各个元组之间或者若干关系之间常常存在各种联系或约束。 （参照完整性－外码约束）</li>
</ul>
</li>
<li><p>动态列级约束</p>
<ul>
<li><ol>
<li>修改列定义时的约束 </li>
</ol>
</li>
<li><ol start="2">
<li>修改列值时的约束</li>
</ol>
</li>
</ul>
</li>
<li><p>动态元组约束 </p>
<ul>
<li>动态元组约束是指修改元组的值时元组中各个字段间需要满足某种约束条件</li>
</ul>
</li>
<li><p>动态关系约束</p>
<ul>
<li>动态关系约束是加在关系变化前后状态上的限制条件，例如事务一致性、原子性等约束条件</li>
</ul>
</li>
</ul>
</div><footer class="post-footer"><div class="post-ending ending"><div class="ending__text">------ END ------</div></div><div class="post-copyright copyright"><div class="copyright-author"><span class="copyright-author__name">Author: </span><span class="copyright-author__value"><a href="https://mikyming.online">MikyMing</a></span></div><div class="copyright-link"><span class="copyright-link__name">Link: </span><span class="copyright-link__value"><a href="https://mikyming.online/2021/10/13/%E6%95%B0%E6%8D%AE%E5%BA%93/">https://mikyming.online/2021/10/13/%E6%95%B0%E6%8D%AE%E5%BA%93/</a></span></div><div class="copyright-notice"><span class="copyright-notice__name">Copyright: </span><span class="copyright-notice__value">All articles in this blog are licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-cn" rel="external nofollow" target="_blank">BY-NC-SA</a> unless stating additionally</span></div></div><div class="post-tags"><span class="post-tags-item"><span class="post-tags-item__icon"><i class="fas fa-tag"></i></span><a class="post-tags-item__link" href="https://mikyming.online/tags/%E6%8A%80%E6%9C%AF%E6%8E%A2%E7%A9%B6/">技术探究</a></span></div><nav class="post-paginator paginator"><div class="paginator-prev"><a class="paginator-prev__link" href="/2022/01/19/%E7%94%B5%E5%AD%90%E4%B9%A6%E8%AF%84%E6%B5%8B/"><span class="paginator-prev__icon"><i class="fas fa-angle-left"></i></span><span class="paginator-prev__text">电子书网站评测</span></a></div><div class="paginator-next"><a class="paginator-next__link" href="/2021/01/06/%E8%BD%AF%E4%BB%B6%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84/"><span class="paginator-prev__text">软件体系结构</span><span class="paginator-next__icon"><i class="fas fa-angle-right"></i></span></a></div></nav></footer></div></div></div><div class="sidebar-wrap" id="sidebar-wrap"><aside class="sidebar" id="sidebar"><div class="sidebar-nav"><span class="sidebar-nav-toc current">Catalog</span><span class="sidebar-nav-ov">Overview</span></div><section class="sidebar-toc"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#绪论"><span class="toc-number">1.</span> <span class="toc-text">
          绪论</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#数据管理的三个阶段"><span class="toc-number">1.1.</span> <span class="toc-text">
          数据管理的三个阶段</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#基本术语"><span class="toc-number">1.2.</span> <span class="toc-text">
          基本术语</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据库的三要素"><span class="toc-number">1.3.</span> <span class="toc-text">
          数据库的三要素</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据模型"><span class="toc-number">1.4.</span> <span class="toc-text">
          数据模型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#联系的种类"><span class="toc-number">1.5.</span> <span class="toc-text">
          联系的种类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#概念模型的表示方法"><span class="toc-number">1.6.</span> <span class="toc-text">
          概念模型的表示方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#基本数据模型"><span class="toc-number">1.7.</span> <span class="toc-text">
          基本数据模型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据库系统的体系结构"><span class="toc-number">1.8.</span> <span class="toc-text">
          数据库系统的体系结构</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#关系模型"><span class="toc-number">2.</span> <span class="toc-text">
          关系模型</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#关系模型组成的三要素"><span class="toc-number">2.1.</span> <span class="toc-text">
          关系模型组成的三要素</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#基本关系的六大性质"><span class="toc-number">2.2.</span> <span class="toc-text">
          基本关系的六大性质</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#关系模型中的三类完整性约束"><span class="toc-number">2.3.</span> <span class="toc-text">
          关系模型中的三类完整性约束</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#关系代数"><span class="toc-number">3.</span> <span class="toc-text">
          关系代数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#概述"><span class="toc-number">3.1.</span> <span class="toc-text">
          概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#关系代数的运算"><span class="toc-number">3.2.</span> <span class="toc-text">
          关系代数的运算</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#关系代数-1"><span class="toc-number">3.3.</span> <span class="toc-text">
          关系代数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#数据库语言SQL"><span class="toc-number">4.</span> <span class="toc-text">
          数据库语言SQL</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL的发展"><span class="toc-number">4.1.</span> <span class="toc-text">
          SQL的发展</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#非过程化语言"><span class="toc-number">4.2.</span> <span class="toc-text">
          非过程化语言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL的形式"><span class="toc-number">4.3.</span> <span class="toc-text">
          SQL的形式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL语言主要组成部分"><span class="toc-number">4.4.</span> <span class="toc-text">
          SQL语言主要组成部分</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL语句"><span class="toc-number">4.5.</span> <span class="toc-text">
          SQL语句</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#视-图-VIEW"><span class="toc-number">4.6.</span> <span class="toc-text">
          视     图   (VIEW)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#索引"><span class="toc-number">4.7.</span> <span class="toc-text">
          索引</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#约束"><span class="toc-number">4.8.</span> <span class="toc-text">
          约束</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL-SERVER权限管理"><span class="toc-number">4.9.</span> <span class="toc-text">
          SQL SERVER权限管理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#查询优化"><span class="toc-number">5.</span> <span class="toc-text">
          查询优化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#概述-1"><span class="toc-number">5.1.</span> <span class="toc-text">
          概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#查询优化-1"><span class="toc-number">5.2.</span> <span class="toc-text">
          查询优化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#关系数据库设计理论"><span class="toc-number">6.</span> <span class="toc-text">
          关系数据库设计理论</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#设计一个好的关系数据库系统，关键是要设计一个好的数据库模式（数据库逻辑设计问题）"><span class="toc-number">6.1.</span> <span class="toc-text">
          设计一个好的关系数据库系统，关键是要设计一个好的数据库模式（数据库逻辑设计问题）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据库逻辑设计主要解决的问题"><span class="toc-number">6.2.</span> <span class="toc-text">
          数据库逻辑设计主要解决的问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#“不好”的数据库设计"><span class="toc-number">6.3.</span> <span class="toc-text">
          “不好”的数据库设计</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#函数依赖"><span class="toc-number">6.4.</span> <span class="toc-text">
          函数依赖</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#完全函数依赖与部分函数依赖"><span class="toc-number">6.5.</span> <span class="toc-text">
          完全函数依赖与部分函数依赖</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#码的形式定义"><span class="toc-number">6.6.</span> <span class="toc-text">
          码的形式定义</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#规范化"><span class="toc-number">6.7.</span> <span class="toc-text">
          规范化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#数据库设计"><span class="toc-number">7.</span> <span class="toc-text">
          数据库设计</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#概述-2"><span class="toc-number">7.1.</span> <span class="toc-text">
          概述</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据库设计的步骤"><span class="toc-number">7.2.</span> <span class="toc-text">
          数据库设计的步骤</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据字典"><span class="toc-number">7.3.</span> <span class="toc-text">
          数据字典</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#设计概念结构通常有四类方法"><span class="toc-number">7.4.</span> <span class="toc-text">
          设计概念结构通常有四类方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#E-R图"><span class="toc-number">7.5.</span> <span class="toc-text">
          E-R图</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#逻辑结构设计阶段"><span class="toc-number">7.6.</span> <span class="toc-text">
          逻辑结构设计阶段</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据模型的优化"><span class="toc-number">7.7.</span> <span class="toc-text">
          数据模型的优化</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#设计用户子模式"><span class="toc-number">7.8.</span> <span class="toc-text">
          设计用户子模式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据库物理设计"><span class="toc-number">7.9.</span> <span class="toc-text">
          数据库物理设计</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#数据库恢复技术"><span class="toc-number">8.</span> <span class="toc-text">
          数据库恢复技术</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#什么是事务"><span class="toc-number">8.1.</span> <span class="toc-text">
          什么是事务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#事务结束"><span class="toc-number">8.2.</span> <span class="toc-text">
          事务结束</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#事务的特性-ACID特性"><span class="toc-number">8.3.</span> <span class="toc-text">
          事务的特性(ACID特性)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#故障"><span class="toc-number">8.4.</span> <span class="toc-text">
          故障</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#恢复操作的基本原理"><span class="toc-number">8.5.</span> <span class="toc-text">
          恢复操作的基本原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#恢复的实现技术"><span class="toc-number">8.6.</span> <span class="toc-text">
          恢复的实现技术</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#并发控制"><span class="toc-number">9.</span> <span class="toc-text">
          并发控制</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#多事务执行方式"><span class="toc-number">9.1.</span> <span class="toc-text">
          多事务执行方式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#事务并发执行带来的问题"><span class="toc-number">9.2.</span> <span class="toc-text">
          事务并发执行带来的问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#并发控制机制的任务"><span class="toc-number">9.3.</span> <span class="toc-text">
          并发控制机制的任务</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#并发操作带来的数据不一致性"><span class="toc-number">9.4.</span> <span class="toc-text">
          并发操作带来的数据不一致性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#封锁"><span class="toc-number">9.5.</span> <span class="toc-text">
          封锁</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#完整性约束"><span class="toc-number">10.</span> <span class="toc-text">
          完整性约束</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#完整性约束的分类"><span class="toc-number">10.1.</span> <span class="toc-text">
          完整性约束的分类</span></a></li></ol></li></ol></section><!-- ov = overview--><section class="sidebar-ov hide"><div class="sidebar-ov-author"><div class="sidebar-ov-author__avatar"><img class="sidebar-ov-author__avatar_img" src="/images/icons/touxiang.jpg" alt="avatar"></div><p class="sidebar-ov-author__text">write code and love life</p></div><div class="sidebar-ov-social"><a class="sidebar-ov-social-item" href="https://github.com/5522mike/" target="_blank" rel="noopener" data-popover="Github" data-popover-pos="up"><span class="sidebar-ov-social-item__icon"><i class="fab fa-github"></i></span></a><a class="sidebar-ov-social-item" href="mailto:wuyyming@gmail.com" target="_blank" rel="noopener" data-popover="social.email" data-popover-pos="up"><span class="sidebar-ov-social-item__icon"><i class="fas fa-envelope"></i></span></a></div><div class="sidebar-ov-feed"><span class="sidebar-ov-feed-rss"><a class="sidebar-ov-feed-rss__link" href="/atom.xml" target="_blank" rel="noopener"><span class="sidebar-ov-feed-rss__icon"><i class="fas fa-rss"></i></span><span>RSS Subscribe</span></a></span></div><div class="sidebar-ov-state"><a class="sidebar-ov-state-item sidebar-ov-state-item--posts" href="/archives/"><div class="sidebar-ov-state-item__count">24</div><div class="sidebar-ov-state-item__name">Archives</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--categories" href="/categories/"><div class="sidebar-ov-state-item__count">4</div><div class="sidebar-ov-state-item__name">Categories</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--tags" href="/tags/"><div class="sidebar-ov-state-item__count">6</div><div class="sidebar-ov-state-item__name">Tags</div></a></div><div class="sidebar-ov-cc"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-cn" target="_blank" rel="noopener" data-popover="Creative Commons" data-popover-pos="up"><img src="/images/cc-by-nc-sa.svg"></a></div></section><div class="sidebar-reading"><div class="sidebar-reading-info"><span class="sidebar-reading-info__text">You have read </span><span class="sidebar-reading-info__num">0</span></div><div class="sidebar-reading-line"></div></div></aside></div><div class="clearfix"></div></div></main><footer class="footer" id="footer"><div class="footer-inner"><div><span>Copyright © 2022</span><span class="footer__icon"><i class="fas fa-heart"></i></span><span>MikyMing</span></div><div><span>Powered by <a href="http://hexo.io/" title="Hexo" target="_blank" rel="noopener">Hexo</a></span><span> v4.0.0</span><span class="footer__devider">|</span><span>Theme - <a href="https://github.com/liuyib/hexo-theme-stun/" title="Stun" target="_blank" rel="noopener">Stun</a></span><span> v2.0.0-rc.0</span></div><div class="busuanzi"><span class="busuanzi-siteuv"><span class="busuanzi-siteuv__icon" data-popover-pos="up" data-popover="Unique Visitor"><i class="fas fa-user"></i></span><span class="busuanzi-siteuv__value" id="busuanzi_value_site_uv"></span></span><span class="busuanzi-sitepv"><span class="busuanzi-siteuv__icon" data-popover-pos="up" data-popover="Page View"><i class="fas fa-eye"></i></span><span class="busuanzi-siteuv__value" id="busuanzi_value_site_pv"></span></span></div></div></footer><div class="loading-bar" id="loading-bar"><div class="loading-bar__progress"></div></div><div class="back2top" id="back2top"><span class="back2top__icon"><i class="fas fa-rocket"></i></span></div></div><div class="search-mask"></div><div class="search-popup"><span class="search-close"></span><div class="search-input"><input placeholder="Search for Posts (Support multiple keywords)"></div><div class="search-results"></div></div><script src="https://cdn.jsdelivr.net/npm/jquery@v3.4.1/dist/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.ui.min.js"></script><script src="https://cdn.jsdelivr.net/npm/ribbon.js@latest/dist/ribbon.min.js" size="120" alpha="0.6" zIndex="-1"></script><script>function initSearch() {
  var isXML = true;
  var search_path = 'search.json';

  if (!search_path) {
    search_path = 'search.xml';
  } else if (/json$/i.test(search_path)) {
    isXML = false;
  }

  var path = '/' + search_path;
  $.ajax({
    url: path,
    dataType: isXML ? 'xml' : 'json',
    async: true,
    success: function (res) {
      var datas = isXML ? $('entry', res).map(function () {
        // 将 XML 转为 JSON
        return {
          title: $('title', this).text(),
          content: $('content', this).text(),
          url: $('url', this).text()
        };
      }).get() : res;
      var $input = $('.search-input input');
      var $result = $('.search-results');
      // 搜索对象（标题、内容）的权重，影响显示顺序
      var WEIGHT = { title: 100, content: 1 };
      var searchPost = function () {
        var searchText = $input.val().toLowerCase().trim();
        // 根据空白字符分隔关键字
        var keywords = searchText.split(/[\s]+/);
        // 搜索结果
        var matchPosts = [];

        // 有多个关键字时，将原文字整个保存下来
        if (keywords.length > 1) {
          keywords.push(searchText);
        }
        // 防止未输入字符时搜索
        if (searchText.length > 0) {
          datas.forEach(function (data) {
            var isMatch  = false;
            // 没有标题的文章使用预设的 i18n 变量代替
            var title = (data.title && data.title.trim()) || '[ Untitled ]';
            var titleLower = title && title.toLowerCase();
            // 删除 HTML 标签 和 所有空白字符
            var content = data.content && data.content.replace(/<[^>]+>/g, '');
            var contentLower = content && content.toLowerCase();
            // 删除重复的 /
            var postURL = data.url && decodeURI(data.url).replace(/\/{2,}/g, '/');
            // 标题中匹配到的关键词
            var titleHitSlice = [];
            // 内容中匹配到的关键词
            var contentHitSlice = [];

            keywords.forEach(function (keyword) {
              /**
              * 获取匹配的关键词的索引
              * @param {String} keyword 要匹配的关键字
              * @param {String} text 原文字
              * @param {Boolean} caseSensitive 是否区分大小写
              * @param {Number} weight 匹配对象的权重。权重大的优先显示
              * @return {Array}
              */
              function getIndexByword (word, text, caseSensitive, weight) {
                if (!word || !text) {
                  return [];
                };

                var startIndex = 0; // 每次匹配的开始索引
                var index = -1;     // 匹配到的索引值
                var result = [];    // 匹配结果

                if (!caseSensitive) {
                  word = word.toLowerCase();
                  text = text.toLowerCase();
                }

                while((index = text.indexOf(word, startIndex)) !== -1) {
                  var hasMatch = false;
                  // 索引位置相同的关键词，保留长度较长的
                  titleHitSlice.forEach(function (hit) {
                    if (hit.index === index && hit.word.length < word.length) {
                      hit.word = word;
                      hasMatch = true;
                    }
                  });
                  startIndex = index + word.length;
                  !hasMatch && result.push({ index: index, word: word, weight: weight });
                }
                return result;
              }
              titleHitSlice = titleHitSlice.concat(getIndexByword(keyword, titleLower, false, WEIGHT.title));
              contentHitSlice = contentHitSlice.concat(getIndexByword(keyword, contentLower, false, WEIGHT.content));
            });

            var hitTitle = titleHitSlice.length;
            var hitContent = contentHitSlice.length;

            if (hitTitle > 0 || hitContent > 0) {
              isMatch = true;
            }
            if (isMatch) {
              ;[titleHitSlice, contentHitSlice].forEach(function (hit) {
                // 按照匹配文字的索引的递增顺序排序
                hit.sort(function (left, right) {
                  return left.index - right.index;
                });
              });
              /**
              * 给文本中匹配到的关键词添加标记，从而进行高亮显示
              * @param {String} text 原文本
              * @param {Array} hitSlice 匹配项的索引信息
              * @param {Number} start 开始索引
              * @param {Number} end 结束索引
              * @return {String}
              */
              function highlightKeyword (text, hitSlice, start, end) {
                if (!text || !hitSlice || !hitSlice.length) {
                  return;
                }

                var result = '';
                var startIndex = start;
                var endIndex = end;
                hitSlice.forEach(function (hit) {
                  if (hit.index < startIndex) {
                    return;
                  }

                  var hitWordEnd = hit.index + hit.word.length;
                  result += text.slice(startIndex, hit.index);
                  result += '<b>' + text.slice(hit.index, hitWordEnd) + '</b>';
                  startIndex = hitWordEnd;
                });
                result += text.slice(startIndex, endIndex);
                return result;
              }

              var postData = {};
              // 文章总的搜索权重
              var postWeight = titleHitSlice.length * WEIGHT.title + contentHitSlice.length * WEIGHT.content;
              // 标记匹配关键词后的标题
              var postTitle = highlightKeyword(title, titleHitSlice, 0, title.length) || title;
              // 标记匹配关键词后的内容
              var postContent;
              // 显示内容的长度
              var SHOW_WORD_LENGTH = 200;
              // 命中关键词前的字符显示长度
              var SHOW_WORD_FRONT_LENGTH = 20;
              var SHOW_WORD_END_LENGTH = SHOW_WORD_LENGTH - SHOW_WORD_FRONT_LENGTH;

              // 截取匹配的第一个字符，前后共 200 个字符来显示
              if (contentHitSlice.length > 0) {
                var firstIndex = contentHitSlice[0].index;
                var start = firstIndex > SHOW_WORD_FRONT_LENGTH ? firstIndex - SHOW_WORD_FRONT_LENGTH : 0;
                var end = firstIndex + SHOW_WORD_END_LENGTH;
                postContent = highlightKeyword(content, contentHitSlice, start, end);
              } else { // 未匹配到内容，直接截取前 200 个字符来显示
                postContent = content.slice(0, SHOW_WORD_LENGTH);
              }
              postData.title = postTitle;
              postData.content = postContent;
              postData.url = postURL;
              postData.weight = postWeight;
              matchPosts.push(postData);
            }
          });
        }

        var resultInnerHtml = '';
        if (matchPosts.length) {
          // 按权重递增的顺序排序，使权重大的优先显示
          matchPosts.sort(function (left, right) {
            return right.weight - left.weight;
          });
          resultInnerHtml += '<ul>';
          matchPosts.forEach(function (post) {
            resultInnerHtml += '<li><a class="search-results-title" href="' + post.url + '">';
            resultInnerHtml += post.title;
            resultInnerHtml += '</a><div class="search-results-content">';
            resultInnerHtml += post.content;
            resultInnerHtml += '</div></li>';
          });
          resultInnerHtml += '</ul>';
        } else {
          resultInnerHtml += '<div class="search-results-none"><i class="far fa-meh"></i></div>';
        }
        $result.html(resultInnerHtml);
      };
      $input.on('input', searchPost);
      $input.on('keyup', function (e) {
        if (e.keyCode === Stun.utils.codeToKeyCode('Enter')) {
          searchPost();
        }
      });
    }
  });
}

function closeSearch () {
  $('body').css({ overflow: 'auto' });
  $('.search-popup').css({ display: 'none' });
  $('.search-mask').css({ display: 'none' });
}

window.addEventListener('DOMContentLoaded', function () {
  Stun.utils.pjaxReloadLocalSearch = function () {
    $('.header-nav-search').on('click', function (e) {
      e.stopPropagation();
      $('body').css('overflow', 'hidden');
      $('.search-popup')
        .velocity('stop')
        .velocity('transition.expandIn', {
          duration: 300,
          complete: function () {
            $('.search-popup input').focus();
          }
        });
      $('.search-mask')
        .velocity('stop')
        .velocity('transition.fadeIn', {
          duration: 300
        });

      initSearch();
    });
    $('.search-mask, .search-close').on('click', function () {
      closeSearch();
    });
    $(document).on('keydown', function (e) {
      // Escape <=> 27
      if (e.keyCode === Stun.utils.codeToKeyCode('Escape')) {
        closeSearch();
      }
    });
  };

  Stun.utils.pjaxReloadLocalSearch();
}, false);</script><script src="https://cdn.jsdelivr.net/gh/sukkaw/busuanzi@latest/bsz.pure.mini.js" async></script><script src="/js/utils.js?v=2.0.0-rc.0"></script><script src="/js/stun-boot.js?v=2.0.0-rc.0"></script><script src="/js/scroll.js?v=2.0.0-rc.0"></script><script src="/js/header.js?v=2.0.0-rc.0"></script><script src="/js/sidebar.js?v=2.0.0-rc.0"></script><script>if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js?t=1648616400595')
    .then(function () {console.log('ServiceWorker Register Successfully.')})
    .catch(function (e) {console.error(e)});
}
</script></body></html>